DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
Loading...
Searching...
No Matches
gl_rmain.c
Go to the documentation of this file.
1/*
2Copyright (C) 1996-1997 Id Software, Inc.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20// r_main.c
21
22#include "quakedef.h"
23#include "r_shadow.h"
24#include "polygon.h"
25#include "image.h"
26#include "ft2.h"
27#include "csprogs.h"
28#include "cl_video.h"
29#include "cl_collision.h"
30
31#ifdef WIN32
32// Enable NVIDIA High Performance Graphics while using Integrated Graphics.
33#ifdef __cplusplus
34extern "C" {
35#endif
37#ifdef __cplusplus
38}
39#endif
40#endif
41
44
46
53
54//
55// screen size info
56//
58
59cvar_t r_motionblur = {CF_CLIENT | CF_ARCHIVE, "r_motionblur", "0", "screen motionblur - value represents intensity, somewhere around 0.5 recommended - NOTE: bad performance on multi-gpu!"};
60cvar_t r_damageblur = {CF_CLIENT | CF_ARCHIVE, "r_damageblur", "0", "screen motionblur based on damage - value represents intensity, somewhere around 0.5 recommended - NOTE: bad performance on multi-gpu!"};
61cvar_t r_motionblur_averaging = {CF_CLIENT | CF_ARCHIVE, "r_motionblur_averaging", "0.1", "sliding average reaction time for velocity (higher = slower adaption to change)"};
62cvar_t r_motionblur_randomize = {CF_CLIENT | CF_ARCHIVE, "r_motionblur_randomize", "0.1", "randomizing coefficient to workaround ghosting"};
63cvar_t r_motionblur_minblur = {CF_CLIENT | CF_ARCHIVE, "r_motionblur_minblur", "0.5", "factor of blur to apply at all times (always have this amount of blur no matter what the other factors are)"};
64cvar_t r_motionblur_maxblur = {CF_CLIENT | CF_ARCHIVE, "r_motionblur_maxblur", "0.9", "maxmimum amount of blur"};
65cvar_t r_motionblur_velocityfactor = {CF_CLIENT | CF_ARCHIVE, "r_motionblur_velocityfactor", "1", "factoring in of player velocity to the blur equation - the faster the player moves around the map, the more blur they get"};
66cvar_t r_motionblur_velocityfactor_minspeed = {CF_CLIENT | CF_ARCHIVE, "r_motionblur_velocityfactor_minspeed", "400", "lower value of velocity when it starts to factor into blur equation"};
67cvar_t r_motionblur_velocityfactor_maxspeed = {CF_CLIENT | CF_ARCHIVE, "r_motionblur_velocityfactor_maxspeed", "800", "upper value of velocity when it reaches the peak factor into blur equation"};
68cvar_t r_motionblur_mousefactor = {CF_CLIENT | CF_ARCHIVE, "r_motionblur_mousefactor", "2", "factoring in of mouse acceleration to the blur equation - the faster the player turns their mouse, the more blur they get"};
69cvar_t r_motionblur_mousefactor_minspeed = {CF_CLIENT | CF_ARCHIVE, "r_motionblur_mousefactor_minspeed", "0", "lower value of mouse acceleration when it starts to factor into blur equation"};
70cvar_t r_motionblur_mousefactor_maxspeed = {CF_CLIENT | CF_ARCHIVE, "r_motionblur_mousefactor_maxspeed", "50", "upper value of mouse acceleration when it reaches the peak factor into blur equation"};
71
72cvar_t r_depthfirst = {CF_CLIENT | CF_ARCHIVE, "r_depthfirst", "0", "renders a depth-only version of the scene before normal rendering begins to eliminate overdraw, values: 0 = off, 1 = world depth, 2 = world and model depth"};
73cvar_t r_useinfinitefarclip = {CF_CLIENT | CF_ARCHIVE, "r_useinfinitefarclip", "1", "enables use of a special kind of projection matrix that has an extremely large farclip"};
74cvar_t r_farclip_base = {CF_CLIENT, "r_farclip_base", "65536", "farclip (furthest visible distance) for rendering when r_useinfinitefarclip is 0"};
75cvar_t r_farclip_world = {CF_CLIENT, "r_farclip_world", "2", "adds map size to farclip multiplied by this value"};
76cvar_t r_nearclip = {CF_CLIENT, "r_nearclip", "1", "distance from camera of nearclip plane" };
77cvar_t r_deformvertexes = {CF_CLIENT, "r_deformvertexes", "1", "allows use of deformvertexes in shader files (can be turned off to check performance impact)"};
78cvar_t r_transparent = {CF_CLIENT, "r_transparent", "1", "allows use of transparent surfaces (can be turned off to check performance impact)"};
79cvar_t r_transparent_alphatocoverage = {CF_CLIENT, "r_transparent_alphatocoverage", "1", "enables GL_ALPHA_TO_COVERAGE antialiasing technique on alphablend and alphatest surfaces when using vid_samples 2 or higher"};
80cvar_t r_transparent_sortsurfacesbynearest = {CF_CLIENT, "r_transparent_sortsurfacesbynearest", "1", "sort entity and world surfaces by nearest point on bounding box instead of using the center of the bounding box, usually reduces sorting artifacts"};
81cvar_t r_transparent_useplanardistance = {CF_CLIENT, "r_transparent_useplanardistance", "0", "sort transparent meshes by distance from view plane rather than spherical distance to the chosen point"};
82cvar_t r_showoverdraw = {CF_CLIENT, "r_showoverdraw", "0", "shows overlapping geometry"};
83cvar_t r_showbboxes = {CF_CLIENT, "r_showbboxes", "0", "shows bounding boxes of server entities, value controls opacity scaling (1 = 10%, 10 = 100%)"};
84cvar_t r_showbboxes_client = {CF_CLIENT, "r_showbboxes_client", "0", "shows bounding boxes of clientside qc entities, value controls opacity scaling (1 = 10%, 10 = 100%)"};
85cvar_t r_showsurfaces = {CF_CLIENT, "r_showsurfaces", "0", "1 shows surfaces as different colors, or a value of 3 shows an approximation to vertex or object color (for a very approximate view of the game)"};
86cvar_t r_showtris = {CF_CLIENT, "r_showtris", "0", "shows triangle outlines, value controls brightness (can be above 1)"};
87cvar_t r_shownormals = {CF_CLIENT, "r_shownormals", "0", "shows per-vertex surface normals and tangent vectors for bumpmapped lighting"};
88cvar_t r_showlighting = {CF_CLIENT, "r_showlighting", "0", "shows areas lit by lights, useful for finding out why some areas of a map render slowly (bright orange = lots of passes = slow), a value of 2 disables depth testing which can be interesting but not very useful"};
89cvar_t r_showcollisionbrushes = {CF_CLIENT, "r_showcollisionbrushes", "0", "draws collision brushes in quake3 maps (mode 1), mode 2 disables rendering of world (trippy!)"};
90cvar_t r_showcollisionbrushes_polygonfactor = {CF_CLIENT, "r_showcollisionbrushes_polygonfactor", "-1", "expands outward the brush polygons a little bit, used to make collision brushes appear infront of walls"};
91cvar_t r_showcollisionbrushes_polygonoffset = {CF_CLIENT, "r_showcollisionbrushes_polygonoffset", "0", "nudges brush polygon depth in hardware depth units, used to make collision brushes appear infront of walls"};
92cvar_t r_showdisabledepthtest = {CF_CLIENT, "r_showdisabledepthtest", "0", "disables depth testing on r_show* cvars, allowing you to see what hidden geometry the graphics card is processing"};
93cvar_t r_showspriteedges = {CF_CLIENT, "r_showspriteedges", "0", "renders a debug outline to show the polygon shape of each sprite frame rendered (may be 2 or more in case of interpolated animations), for debugging rendering bugs with specific view types"};
94cvar_t r_showparticleedges = {CF_CLIENT, "r_showparticleedges", "0", "renders a debug outline to show the polygon shape of each particle, for debugging rendering bugs with specific view types"};
95cvar_t r_drawportals = {CF_CLIENT, "r_drawportals", "0", "shows portals (separating polygons) in world interior in quake1 maps"};
96cvar_t r_drawentities = {CF_CLIENT, "r_drawentities","1", "draw entities (doors, players, projectiles, etc)"};
97cvar_t r_draw2d = {CF_CLIENT, "r_draw2d","1", "draw 2D stuff (dangerous to turn off)"};
98cvar_t r_drawworld = {CF_CLIENT, "r_drawworld","1", "draw world (most static stuff)"};
99cvar_t r_drawviewmodel = {CF_CLIENT, "r_drawviewmodel","1", "draw your weapon model"};
100cvar_t r_drawexteriormodel = {CF_CLIENT, "r_drawexteriormodel","1", "draw your player model (e.g. in chase cam, reflections)"};
101cvar_t r_cullentities_trace = {CF_CLIENT, "r_cullentities_trace", "1", "probabistically cull invisible entities"};
102cvar_t r_cullentities_trace_entityocclusion = {CF_CLIENT, "r_cullentities_trace_entityocclusion", "1", "check for occluding entities such as doors, not just world hull"};
103cvar_t r_cullentities_trace_samples = {CF_CLIENT, "r_cullentities_trace_samples", "2", "number of samples to test for entity culling (in addition to center sample)"};
104cvar_t r_cullentities_trace_tempentitysamples = {CF_CLIENT, "r_cullentities_trace_tempentitysamples", "-1", "number of samples to test for entity culling of temp entities (including all CSQC entities), -1 disables trace culling on these entities to prevent flicker (pvs still applies)"};
105cvar_t r_cullentities_trace_enlarge = {CF_CLIENT, "r_cullentities_trace_enlarge", "0", "box enlargement for entity culling"};
106cvar_t r_cullentities_trace_expand = {CF_CLIENT, "r_cullentities_trace_expand", "0", "box expanded by this many units for entity culling"};
107cvar_t r_cullentities_trace_pad = {CF_CLIENT, "r_cullentities_trace_pad", "8", "accept traces that hit within this many units of the box"};
108cvar_t r_cullentities_trace_delay = {CF_CLIENT, "r_cullentities_trace_delay", "1", "number of seconds until the entity gets actually culled"};
109cvar_t r_cullentities_trace_eyejitter = {CF_CLIENT, "r_cullentities_trace_eyejitter", "16", "randomly offset rays from the eye by this much to reduce the odds of flickering"};
110cvar_t r_sortentities = {CF_CLIENT, "r_sortentities", "0", "sort entities before drawing (might be faster)"};
111cvar_t r_speeds = {CF_CLIENT, "r_speeds","0", "displays rendering statistics and per-subsystem timings"};
112cvar_t r_fullbright = {CF_CLIENT, "r_fullbright","0", "makes map very bright and renders faster"};
113
114cvar_t r_fullbright_directed = {CF_CLIENT, "r_fullbright_directed", "0", "render fullbright things (unlit worldmodel and EF_FULLBRIGHT entities, but not fullbright shaders) using a constant light direction instead to add more depth while keeping uniform brightness"};
115cvar_t r_fullbright_directed_ambient = {CF_CLIENT, "r_fullbright_directed_ambient", "0.5", "ambient light multiplier for directed fullbright"};
116cvar_t r_fullbright_directed_diffuse = {CF_CLIENT, "r_fullbright_directed_diffuse", "0.75", "diffuse light multiplier for directed fullbright"};
117cvar_t r_fullbright_directed_pitch = {CF_CLIENT, "r_fullbright_directed_pitch", "20", "constant pitch direction ('height') of the fake light source to use for fullbright"};
118cvar_t r_fullbright_directed_pitch_relative = {CF_CLIENT, "r_fullbright_directed_pitch_relative", "0", "whether r_fullbright_directed_pitch is interpreted as absolute (0) or relative (1) pitch"};
119
120cvar_t r_wateralpha = {CF_CLIENT | CF_ARCHIVE, "r_wateralpha","1", "opacity of water polygons"};
121cvar_t r_dynamic = {CF_CLIENT | CF_ARCHIVE, "r_dynamic","1", "enables dynamic lights (rocket glow and such)"};
122cvar_t r_fullbrights = {CF_CLIENT | CF_ARCHIVE, "r_fullbrights", "1", "enables glowing pixels in quake textures (changes need r_restart to take effect)"};
123cvar_t r_shadows = {CF_CLIENT | CF_ARCHIVE, "r_shadows", "0", "casts fake stencil shadows from models onto the world (rtlights are unaffected by this); when set to 2, always cast the shadows in the direction set by r_shadows_throwdirection, otherwise use the model lighting."};
124cvar_t r_shadows_darken = {CF_CLIENT | CF_ARCHIVE, "r_shadows_darken", "0.5", "how much shadowed areas will be darkened"};
125cvar_t r_shadows_throwdistance = {CF_CLIENT | CF_ARCHIVE, "r_shadows_throwdistance", "500", "how far to cast shadows from models"};
126cvar_t r_shadows_throwdirection = {CF_CLIENT | CF_ARCHIVE, "r_shadows_throwdirection", "0 0 -1", "override throwing direction for r_shadows 2"};
127cvar_t r_shadows_drawafterrtlighting = {CF_CLIENT | CF_ARCHIVE, "r_shadows_drawafterrtlighting", "0", "draw fake shadows AFTER realtime lightning is drawn. May be useful for simulating fast sunlight on large outdoor maps with only one noshadow rtlight. The price is less realistic appearance of dynamic light shadows."};
128cvar_t r_shadows_castfrombmodels = {CF_CLIENT | CF_ARCHIVE, "r_shadows_castfrombmodels", "0", "do cast shadows from bmodels"};
129cvar_t r_shadows_focus = {CF_CLIENT | CF_ARCHIVE, "r_shadows_focus", "0 0 0", "offset the shadowed area focus"};
130cvar_t r_shadows_shadowmapscale = {CF_CLIENT | CF_ARCHIVE, "r_shadows_shadowmapscale", "0.25", "higher values increase shadowmap quality at a cost of area covered (multiply global shadowmap precision) for fake shadows. Needs shadowmapping ON."};
131cvar_t r_shadows_shadowmapbias = {CF_CLIENT | CF_ARCHIVE, "r_shadows_shadowmapbias", "-1", "sets shadowmap bias for fake shadows. -1 sets the value of r_shadow_shadowmapping_bias. Needs shadowmapping ON."};
132cvar_t r_q1bsp_skymasking = {CF_CLIENT, "r_q1bsp_skymasking", "1", "allows sky polygons in quake1 maps to obscure other geometry"};
133cvar_t r_polygonoffset_submodel_factor = {CF_CLIENT, "r_polygonoffset_submodel_factor", "0", "biases depth values of world submodels such as doors, to prevent z-fighting artifacts in Quake maps"};
134cvar_t r_polygonoffset_submodel_offset = {CF_CLIENT, "r_polygonoffset_submodel_offset", "14", "biases depth values of world submodels such as doors, to prevent z-fighting artifacts in Quake maps"};
135cvar_t r_polygonoffset_decals_factor = {CF_CLIENT, "r_polygonoffset_decals_factor", "0", "biases depth values of decals to prevent z-fighting artifacts"};
136cvar_t r_polygonoffset_decals_offset = {CF_CLIENT, "r_polygonoffset_decals_offset", "-14", "biases depth values of decals to prevent z-fighting artifacts"};
137cvar_t r_fog_exp2 = {CF_CLIENT, "r_fog_exp2", "0", "uses GL_EXP2 fog (as in Nehahra) rather than realistic GL_EXP fog"};
138cvar_t r_fog_clear = {CF_CLIENT, "r_fog_clear", "1", "clears renderbuffer with fog color before render starts"};
139cvar_t r_drawfog = {CF_CLIENT | CF_ARCHIVE, "r_drawfog", "1", "allows one to disable fog rendering"};
140cvar_t r_transparentdepthmasking = {CF_CLIENT | CF_ARCHIVE, "r_transparentdepthmasking", "0", "enables depth writes on transparent meshes whose materially is normally opaque, this prevents seeing the inside of a transparent mesh"};
141cvar_t r_transparent_sortmindist = {CF_CLIENT | CF_ARCHIVE, "r_transparent_sortmindist", "0", "lower distance limit for transparent sorting"};
142cvar_t r_transparent_sortmaxdist = {CF_CLIENT | CF_ARCHIVE, "r_transparent_sortmaxdist", "32768", "upper distance limit for transparent sorting"};
143cvar_t r_transparent_sortarraysize = {CF_CLIENT | CF_ARCHIVE, "r_transparent_sortarraysize", "4096", "number of distance-sorting layers"};
144cvar_t r_celshading = {CF_CLIENT | CF_ARCHIVE, "r_celshading", "0", "cartoon-style light shading (OpenGL 2.x only)"}; // FIXME remove OpenGL 2.x only once implemented for DX9
145cvar_t r_celoutlines = {CF_CLIENT | CF_ARCHIVE, "r_celoutlines", "0", "cartoon-style outlines (requires r_shadow_deferred)"};
146
147cvar_t gl_fogenable = {CF_CLIENT, "gl_fogenable", "0", "nehahra fog enable (for Nehahra compatibility only)"};
148cvar_t gl_fogdensity = {CF_CLIENT, "gl_fogdensity", "0.25", "nehahra fog density (recommend values below 0.1) (for Nehahra compatibility only)"};
149cvar_t gl_fogred = {CF_CLIENT, "gl_fogred","0.3", "nehahra fog color red value (for Nehahra compatibility only)"};
150cvar_t gl_foggreen = {CF_CLIENT, "gl_foggreen","0.3", "nehahra fog color green value (for Nehahra compatibility only)"};
151cvar_t gl_fogblue = {CF_CLIENT, "gl_fogblue","0.3", "nehahra fog color blue value (for Nehahra compatibility only)"};
152cvar_t gl_fogstart = {CF_CLIENT, "gl_fogstart", "0", "nehahra fog start distance (for Nehahra compatibility only)"};
153cvar_t gl_fogend = {CF_CLIENT, "gl_fogend","0", "nehahra fog end distance (for Nehahra compatibility only)"};
154cvar_t gl_skyclip = {CF_CLIENT, "gl_skyclip", "4608", "nehahra farclip distance - the real fog end (for Nehahra compatibility only)"};
155
156cvar_t r_texture_dds_load = {CF_CLIENT | CF_ARCHIVE, "r_texture_dds_load", "0", "load compressed dds/filename.dds texture instead of filename.tga, if the file exists (requires driver support)"};
157cvar_t r_texture_dds_save = {CF_CLIENT | CF_ARCHIVE, "r_texture_dds_save", "0", "save compressed dds/filename.dds texture when filename.tga is loaded, so that it can be loaded instead next time"};
158
159cvar_t r_usedepthtextures = {CF_CLIENT | CF_ARCHIVE, "r_usedepthtextures", "1", "use depth texture instead of depth renderbuffer where possible, uses less video memory but may render slower (or faster) depending on hardware"};
160cvar_t r_viewfbo = {CF_CLIENT | CF_ARCHIVE, "r_viewfbo", "0", "enables use of an 8bit (1) or 16bit (2) or 32bit (3) per component float framebuffer render, which may be at a different resolution than the video mode; the default setting of 0 uses a framebuffer render when required, and renders directly to the screen otherwise"};
161cvar_t r_rendertarget_debug = {CF_CLIENT, "r_rendertarget_debug", "-1", "replaces the view with the contents of the specified render target (by number - note that these can fluctuate depending on scene)"};
162cvar_t r_viewscale = {CF_CLIENT | CF_ARCHIVE, "r_viewscale", "1", "scaling factor for resolution of the fbo rendering method, must be > 0, can be above 1 for a costly antialiasing behavior, typical values are 0.5 for 1/4th as many pixels rendered, or 1 for normal rendering"};
163cvar_t r_viewscale_fpsscaling = {CF_CLIENT | CF_ARCHIVE, "r_viewscale_fpsscaling", "0", "change resolution based on framerate"};
164cvar_t r_viewscale_fpsscaling_min = {CF_CLIENT | CF_ARCHIVE, "r_viewscale_fpsscaling_min", "0.0625", "worst acceptable quality"};
165cvar_t r_viewscale_fpsscaling_multiply = {CF_CLIENT | CF_ARCHIVE, "r_viewscale_fpsscaling_multiply", "5", "adjust quality up or down by the frametime difference from 1.0/target, multiplied by this factor"};
166cvar_t r_viewscale_fpsscaling_stepsize = {CF_CLIENT | CF_ARCHIVE, "r_viewscale_fpsscaling_stepsize", "0.01", "smallest adjustment to hit the target framerate (this value prevents minute oscillations)"};
167cvar_t r_viewscale_fpsscaling_stepmax = {CF_CLIENT | CF_ARCHIVE, "r_viewscale_fpsscaling_stepmax", "1.00", "largest adjustment to hit the target framerate (this value prevents wild overshooting of the estimate)"};
168cvar_t r_viewscale_fpsscaling_target = {CF_CLIENT | CF_ARCHIVE, "r_viewscale_fpsscaling_target", "70", "desired framerate"};
169
170cvar_t r_glsl_skeletal = {CF_CLIENT | CF_ARCHIVE, "r_glsl_skeletal", "1", "render skeletal models faster using a gpu-skinning technique"};
171cvar_t r_glsl_deluxemapping = {CF_CLIENT | CF_ARCHIVE, "r_glsl_deluxemapping", "1", "use per pixel lighting on deluxemap-compiled q3bsp maps (or a value of 2 forces deluxemap shading even without deluxemaps)"};
172cvar_t r_glsl_offsetmapping = {CF_CLIENT | CF_ARCHIVE, "r_glsl_offsetmapping", "0", "offset mapping effect (also known as parallax mapping or virtual displacement mapping)"};
173cvar_t r_glsl_offsetmapping_steps = {CF_CLIENT | CF_ARCHIVE, "r_glsl_offsetmapping_steps", "2", "offset mapping steps (note: too high values may be not supported by your GPU)"};
174cvar_t r_glsl_offsetmapping_reliefmapping = {CF_CLIENT | CF_ARCHIVE, "r_glsl_offsetmapping_reliefmapping", "0", "relief mapping effect (higher quality)"};
175cvar_t r_glsl_offsetmapping_reliefmapping_steps = {CF_CLIENT | CF_ARCHIVE, "r_glsl_offsetmapping_reliefmapping_steps", "10", "relief mapping steps (note: too high values may be not supported by your GPU)"};
176cvar_t r_glsl_offsetmapping_reliefmapping_refinesteps = {CF_CLIENT | CF_ARCHIVE, "r_glsl_offsetmapping_reliefmapping_refinesteps", "5", "relief mapping refine steps (these are a binary search executed as the last step as given by r_glsl_offsetmapping_reliefmapping_steps)"};
177cvar_t r_glsl_offsetmapping_scale = {CF_CLIENT | CF_ARCHIVE, "r_glsl_offsetmapping_scale", "0.04", "how deep the offset mapping effect is"};
178cvar_t r_glsl_offsetmapping_lod = {CF_CLIENT | CF_ARCHIVE, "r_glsl_offsetmapping_lod", "0", "apply distance-based level-of-detail correction to number of offsetmappig steps, effectively making it render faster on large open-area maps"};
179cvar_t r_glsl_offsetmapping_lod_distance = {CF_CLIENT | CF_ARCHIVE, "r_glsl_offsetmapping_lod_distance", "32", "first LOD level distance, second level (-50% steps) is 2x of this, third (33%) - 3x etc."};
180cvar_t r_glsl_postprocess = {CF_CLIENT | CF_ARCHIVE, "r_glsl_postprocess", "0", "use a GLSL postprocessing shader"};
181cvar_t r_glsl_postprocess_uservec1 = {CF_CLIENT | CF_ARCHIVE, "r_glsl_postprocess_uservec1", "0 0 0 0", "a 4-component vector to pass as uservec1 to the postprocessing shader (only useful if default.glsl has been customized)"};
182cvar_t r_glsl_postprocess_uservec2 = {CF_CLIENT | CF_ARCHIVE, "r_glsl_postprocess_uservec2", "0 0 0 0", "a 4-component vector to pass as uservec2 to the postprocessing shader (only useful if default.glsl has been customized)"};
183cvar_t r_glsl_postprocess_uservec3 = {CF_CLIENT | CF_ARCHIVE, "r_glsl_postprocess_uservec3", "0 0 0 0", "a 4-component vector to pass as uservec3 to the postprocessing shader (only useful if default.glsl has been customized)"};
184cvar_t r_glsl_postprocess_uservec4 = {CF_CLIENT | CF_ARCHIVE, "r_glsl_postprocess_uservec4", "0 0 0 0", "a 4-component vector to pass as uservec4 to the postprocessing shader (only useful if default.glsl has been customized)"};
185cvar_t r_glsl_postprocess_uservec1_enable = {CF_CLIENT | CF_ARCHIVE, "r_glsl_postprocess_uservec1_enable", "1", "enables postprocessing uservec1 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"};
186cvar_t r_glsl_postprocess_uservec2_enable = {CF_CLIENT | CF_ARCHIVE, "r_glsl_postprocess_uservec2_enable", "1", "enables postprocessing uservec2 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"};
187cvar_t r_glsl_postprocess_uservec3_enable = {CF_CLIENT | CF_ARCHIVE, "r_glsl_postprocess_uservec3_enable", "1", "enables postprocessing uservec3 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"};
188cvar_t r_glsl_postprocess_uservec4_enable = {CF_CLIENT | CF_ARCHIVE, "r_glsl_postprocess_uservec4_enable", "1", "enables postprocessing uservec4 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"};
189cvar_t r_colorfringe = {CF_CLIENT | CF_ARCHIVE, "r_colorfringe", "0", "Chromatic aberration. Values higher than 0.025 will noticeably distort the image"};
190cvar_t r_fxaa = {CF_CLIENT | CF_ARCHIVE, "r_fxaa", "0", "fast approximate anti aliasing"};
191
192cvar_t r_water = {CF_CLIENT | CF_ARCHIVE, "r_water", "0", "whether to use reflections and refraction on water surfaces (note: r_wateralpha must be set below 1)"};
193cvar_t r_water_cameraentitiesonly = {CF_CLIENT | CF_ARCHIVE, "r_water_cameraentitiesonly", "0", "whether to only show QC-defined reflections/refractions (typically used for camera- or portal-like effects)"};
194cvar_t r_water_clippingplanebias = {CF_CLIENT | CF_ARCHIVE, "r_water_clippingplanebias", "1", "a rather technical setting which avoids black pixels around water edges"};
195cvar_t r_water_resolutionmultiplier = {CF_CLIENT | CF_ARCHIVE, "r_water_resolutionmultiplier", "0.5", "multiplier for screen resolution when rendering refracted/reflected scenes, 1 is full quality, lower values are faster"};
196cvar_t r_water_refractdistort = {CF_CLIENT | CF_ARCHIVE, "r_water_refractdistort", "0.01", "how much water refractions shimmer"};
197cvar_t r_water_reflectdistort = {CF_CLIENT | CF_ARCHIVE, "r_water_reflectdistort", "0.01", "how much water reflections shimmer"};
198cvar_t r_water_scissormode = {CF_CLIENT, "r_water_scissormode", "3", "scissor (1) or cull (2) or both (3) water renders"};
199cvar_t r_water_lowquality = {CF_CLIENT, "r_water_lowquality", "0", "special option to accelerate water rendering: 1 disables all dynamic lights, 2 disables particles too"};
200cvar_t r_water_hideplayer = {CF_CLIENT | CF_ARCHIVE, "r_water_hideplayer", "0", "if set to 1 then player will be hidden in refraction views, if set to 2 then player will also be hidden in reflection views, player is always visible in camera views"};
201
202cvar_t r_lerpsprites = {CF_CLIENT | CF_ARCHIVE, "r_lerpsprites", "0", "enables animation smoothing on sprites"};
203cvar_t r_lerpmodels = {CF_CLIENT | CF_ARCHIVE, "r_lerpmodels", "1", "enables animation smoothing on models"};
204cvar_t r_nolerp_list = {CF_CLIENT | CF_ARCHIVE, "r_nolerp_list", "progs/v_nail.mdl,progs/v_nail2.mdl,progs/flame.mdl,progs/flame2.mdl,progs/braztall.mdl,progs/brazshrt.mdl,progs/longtrch.mdl,progs/flame_pyre.mdl,progs/v_saw.mdl,progs/v_xfist.mdl,progs/h2stuff/newfire.mdl", "comma separated list of models that will not have their animations smoothed"};
205cvar_t r_lerplightstyles = {CF_CLIENT | CF_ARCHIVE, "r_lerplightstyles", "0", "enable animation smoothing on flickering lights"};
206cvar_t r_waterscroll = {CF_CLIENT | CF_ARCHIVE, "r_waterscroll", "1", "makes water scroll around, value controls how much"};
207
208cvar_t r_bloom = {CF_CLIENT | CF_ARCHIVE, "r_bloom", "0", "enables bloom effect (makes bright pixels affect neighboring pixels)"};
209cvar_t r_bloom_colorscale = {CF_CLIENT | CF_ARCHIVE, "r_bloom_colorscale", "1", "how bright the glow is"};
210
211cvar_t r_bloom_brighten = {CF_CLIENT | CF_ARCHIVE, "r_bloom_brighten", "1", "how bright the glow is, after subtract/power"};
212cvar_t r_bloom_blur = {CF_CLIENT | CF_ARCHIVE, "r_bloom_blur", "4", "how large the glow is"};
213cvar_t r_bloom_resolution = {CF_CLIENT | CF_ARCHIVE, "r_bloom_resolution", "320", "what resolution to perform the bloom effect at (independent of screen resolution)"};
214cvar_t r_bloom_colorexponent = {CF_CLIENT | CF_ARCHIVE, "r_bloom_colorexponent", "1", "how exaggerated the glow is"};
215cvar_t r_bloom_colorsubtract = {CF_CLIENT | CF_ARCHIVE, "r_bloom_colorsubtract", "0.1", "reduces bloom colors by a certain amount"};
216cvar_t r_bloom_scenebrightness = {CF_CLIENT | CF_ARCHIVE, "r_bloom_scenebrightness", "1", "global rendering brightness when bloom is enabled"};
217
218cvar_t r_hdr_scenebrightness = {CF_CLIENT | CF_ARCHIVE, "r_hdr_scenebrightness", "1", "global rendering brightness"};
219cvar_t r_hdr_glowintensity = {CF_CLIENT | CF_ARCHIVE, "r_hdr_glowintensity", "1", "how bright light emitting textures should appear"};
220cvar_t r_hdr_irisadaptation = {CF_CLIENT | CF_ARCHIVE, "r_hdr_irisadaptation", "0", "adjust scene brightness according to light intensity at player location"};
221cvar_t r_hdr_irisadaptation_multiplier = {CF_CLIENT | CF_ARCHIVE, "r_hdr_irisadaptation_multiplier", "2", "brightness at which value will be 1.0"};
222cvar_t r_hdr_irisadaptation_minvalue = {CF_CLIENT | CF_ARCHIVE, "r_hdr_irisadaptation_minvalue", "0.5", "minimum value that can result from multiplier / brightness"};
223cvar_t r_hdr_irisadaptation_maxvalue = {CF_CLIENT | CF_ARCHIVE, "r_hdr_irisadaptation_maxvalue", "4", "maximum value that can result from multiplier / brightness"};
224cvar_t r_hdr_irisadaptation_value = {CF_CLIENT, "r_hdr_irisadaptation_value", "1", "current value as scenebrightness multiplier, changes continuously when irisadaptation is active"};
225cvar_t r_hdr_irisadaptation_fade_up = {CF_CLIENT | CF_ARCHIVE, "r_hdr_irisadaptation_fade_up", "0.1", "fade rate at which value adjusts to darkness"};
226cvar_t r_hdr_irisadaptation_fade_down = {CF_CLIENT | CF_ARCHIVE, "r_hdr_irisadaptation_fade_down", "0.5", "fade rate at which value adjusts to brightness"};
227cvar_t r_hdr_irisadaptation_radius = {CF_CLIENT | CF_ARCHIVE, "r_hdr_irisadaptation_radius", "15", "lighting within this many units of the eye is averaged"};
228
229cvar_t r_smoothnormals_areaweighting = {CF_CLIENT, "r_smoothnormals_areaweighting", "1", "uses significantly faster (and supposedly higher quality) area-weighted vertex normals and tangent vectors rather than summing normalized triangle normals and tangents"};
230
231cvar_t developer_texturelogging = {CF_CLIENT, "developer_texturelogging", "0", "produces a textures.log file containing names of skins and map textures the engine tried to load"};
232
233cvar_t gl_lightmaps = {CF_CLIENT, "gl_lightmaps", "0", "draws only lightmaps, no texture (for level designers), a value of 2 keeps normalmap shading"};
234
235cvar_t r_test = {CF_CLIENT, "r_test", "0", "internal development use only, leave it alone (usually does nothing anyway)"};
236
237cvar_t r_batch_multidraw = {CF_CLIENT | CF_ARCHIVE, "r_batch_multidraw", "1", "issue multiple glDrawElements calls when rendering a batch of surfaces with the same texture (otherwise the index data is copied to make it one draw)"};
238cvar_t r_batch_multidraw_mintriangles = {CF_CLIENT | CF_ARCHIVE, "r_batch_multidraw_mintriangles", "0", "minimum number of triangles to activate multidraw path (copying small groups of triangles may be faster)"};
239cvar_t r_batch_debugdynamicvertexpath = {CF_CLIENT | CF_ARCHIVE, "r_batch_debugdynamicvertexpath", "0", "force the dynamic batching code path for debugging purposes"};
240cvar_t r_batch_dynamicbuffer = {CF_CLIENT | CF_ARCHIVE, "r_batch_dynamicbuffer", "0", "use vertex/index buffers for drawing dynamic and copytriangles batches"};
241
242cvar_t r_glsl_saturation = {CF_CLIENT | CF_ARCHIVE, "r_glsl_saturation", "1", "saturation multiplier (only working in glsl!)"};
243cvar_t r_glsl_saturation_redcompensate = {CF_CLIENT | CF_ARCHIVE, "r_glsl_saturation_redcompensate", "0", "a 'vampire sight' addition to desaturation effect, does compensation for red color, r_glsl_restart is required"};
244
245cvar_t r_glsl_vertextextureblend_usebothalphas = {CF_CLIENT | CF_ARCHIVE, "r_glsl_vertextextureblend_usebothalphas", "0", "use both alpha layers on vertex blended surfaces, each alpha layer sets amount of 'blend leak' on another layer, requires mod_q3shader_force_terrain_alphaflag on."};
246
247// FIXME: This cvar would grow to a ridiculous size after several launches and clean exits when used during surface sorting.
248cvar_t r_framedatasize = {CF_CLIENT | CF_ARCHIVE, "r_framedatasize", "0.5", "size of renderer data cache used during one frame (for skeletal animation caching, light processing, etc)"};
250{
251 {CF_CLIENT | CF_ARCHIVE, "r_buffermegs_vertex", "4", "vertex buffer size for one frame"},
252 {CF_CLIENT | CF_ARCHIVE, "r_buffermegs_index16", "1", "index buffer size for one frame (16bit indices)"},
253 {CF_CLIENT | CF_ARCHIVE, "r_buffermegs_index32", "1", "index buffer size for one frame (32bit indices)"},
254 {CF_CLIENT | CF_ARCHIVE, "r_buffermegs_uniform", "0.25", "uniform buffer size for one frame"},
255};
256
257cvar_t r_q1bsp_lightmap_updates_enabled = {CF_CLIENT, "r_q1bsp_lightmap_updates_enabled", "1", "allow lightmaps to be updated on Q1BSP maps (don't turn this off except for debugging)"};
258cvar_t r_q1bsp_lightmap_updates_combine = {CF_CLIENT | CF_ARCHIVE, "r_q1bsp_lightmap_updates_combine", "2", "combine lightmap texture updates to make fewer glTexSubImage2D calls, modes: 0 = immediately upload lightmaps (may be thousands of small 3x3 updates), 1 = combine to one call, 2 = combine to one full texture update (glTexImage2D) which tells the driver it does not need to lock the resource (faster on most drivers)"};
259cvar_t r_q1bsp_lightmap_updates_hidden_surfaces = {CF_CLIENT | CF_ARCHIVE, "r_q1bsp_lightmap_updates_hidden_surfaces", "0", "update lightmaps on surfaces that are not visible, so that updates only occur on frames where lightstyles changed value (animation or light switches), only makes sense with combine = 2"};
260
262
264
266
269
270int r_uniformbufferalignment = 32; // dynamically updated to match GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT
271
283//rtexture_t *r_texture_fogintensity;
285
286// TODO: hash lookups?
287typedef struct cubemapinfo_s
288{
289 char basename[64];
291}
293
296
298unsigned int r_numqueries;
299unsigned int r_maxqueries;
300
307
310
312extern const float r_screenvertex3f[12];
313const float r_screenvertex3f[12] =
314{
315 0, 0, 0,
316 1, 0, 0,
317 1, 1, 0,
318 0, 1, 0
319};
320
321void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
322{
323 int i;
324 for (i = 0;i < verts;i++)
325 {
326 out[0] = in[0] * r;
327 out[1] = in[1] * g;
328 out[2] = in[2] * b;
329 out[3] = in[3];
330 in += 4;
331 out += 4;
332 }
333}
334
335void R_FillColors(float *out, int verts, float r, float g, float b, float a)
336{
337 int i;
338 for (i = 0;i < verts;i++)
339 {
340 out[0] = r;
341 out[1] = g;
342 out[2] = b;
343 out[3] = a;
344 out += 4;
345 }
346}
347
348// FIXME: move this to client?
349void FOG_clear(void)
350{
351 if (gamemode == GAME_NEHAHRA)
352 {
353 Cvar_Set(&cvars_all, "gl_fogenable", "0");
354 Cvar_Set(&cvars_all, "gl_fogdensity", "0.2");
355 Cvar_Set(&cvars_all, "gl_fogred", "0.3");
356 Cvar_Set(&cvars_all, "gl_foggreen", "0.3");
357 Cvar_Set(&cvars_all, "gl_fogblue", "0.3");
358 }
360 r_refdef.fog_red = 0;
362 r_refdef.fog_blue = 0;
365 r_refdef.fog_end = 16384;
366 r_refdef.fog_height = 1<<30;
369}
370
371static void R_BuildBlankTextures(void)
372{
373 unsigned char data[4];
374 data[2] = 128; // normal X
375 data[1] = 128; // normal Y
376 data[0] = 255; // normal Z
377 data[3] = 255; // height
379 data[0] = 255;
380 data[1] = 255;
381 data[2] = 255;
382 data[3] = 255;
384 data[0] = 128;
385 data[1] = 128;
386 data[2] = 128;
387 data[3] = 255;
389 data[0] = 0;
390 data[1] = 0;
391 data[2] = 0;
392 data[3] = 255;
394}
395
400
401static void R_BuildWhiteCube(void)
402{
403 unsigned char data[6*1*1*4];
404 memset(data, 255, sizeof(data));
406}
407
409{
410 int x, y, side;
411 vec3_t v;
412 vec_t s, t, intensity;
413#define NORMSIZE 64
414 unsigned char *data;
415 data = (unsigned char *)Mem_Alloc(tempmempool, 6*NORMSIZE*NORMSIZE*4);
416 for (side = 0;side < 6;side++)
417 {
418 for (y = 0;y < NORMSIZE;y++)
419 {
420 for (x = 0;x < NORMSIZE;x++)
421 {
422 s = (x + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
423 t = (y + 0.5f) * (2.0f / NORMSIZE) - 1.0f;
424 switch(side)
425 {
426 default:
427 case 0:
428 v[0] = 1;
429 v[1] = -t;
430 v[2] = -s;
431 break;
432 case 1:
433 v[0] = -1;
434 v[1] = -t;
435 v[2] = s;
436 break;
437 case 2:
438 v[0] = s;
439 v[1] = 1;
440 v[2] = t;
441 break;
442 case 3:
443 v[0] = s;
444 v[1] = -1;
445 v[2] = -t;
446 break;
447 case 4:
448 v[0] = s;
449 v[1] = -t;
450 v[2] = 1;
451 break;
452 case 5:
453 v[0] = -s;
454 v[1] = -t;
455 v[2] = -1;
456 break;
457 }
458 intensity = 127.0f / sqrt(DotProduct(v, v));
459 data[((side*64+y)*64+x)*4+2] = (unsigned char)(128.0f + intensity * v[0]);
460 data[((side*64+y)*64+x)*4+1] = (unsigned char)(128.0f + intensity * v[1]);
461 data[((side*64+y)*64+x)*4+0] = (unsigned char)(128.0f + intensity * v[2]);
462 data[((side*64+y)*64+x)*4+3] = 255;
463 }
464 }
465 }
467 Mem_Free(data);
468}
469
470static void R_BuildFogTexture(void)
471{
472 int x, b;
473#define FOGWIDTH 256
474 unsigned char data1[FOGWIDTH][4];
475 //unsigned char data2[FOGWIDTH][4];
476 double d, r, alpha;
477
482
484 for (x = 0;x < FOGMASKTABLEWIDTH;x++)
485 {
488 Con_DPrintf("%f ", d);
489 d = max(0, d);
492 else
495 Con_DPrintf(" : %f ", alpha);
498 Con_DPrintf(" = %f\n", alpha);
500 }
501
502 for (x = 0;x < FOGWIDTH;x++)
503 {
504 b = (int)(r_refdef.fogmasktable[x * (FOGMASKTABLEWIDTH - 1) / (FOGWIDTH - 1)] * 255);
505 data1[x][0] = b;
506 data1[x][1] = b;
507 data1[x][2] = b;
508 data1[x][3] = 255;
509 //data2[x][0] = 255 - b;
510 //data2[x][1] = 255 - b;
511 //data2[x][2] = 255 - b;
512 //data2[x][3] = 255;
513 }
515 {
516 R_UpdateTexture(r_texture_fogattenuation, &data1[0][0], 0, 0, 0, FOGWIDTH, 1, 1, 0);
517 //R_UpdateTexture(r_texture_fogattenuation, &data2[0][0], 0, 0, 0, FOGWIDTH, 1, 1, 0);
518 }
519 else
520 {
522 //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_BGRA, TEXF_FORCELINEAR | TEXF_CLAMP, NULL);
523 }
524}
525
526static void R_BuildFogHeightTexture(void)
527{
528 unsigned char *inpixels;
529 int size;
530 int x;
531 int y;
532 int j;
533 float c[4];
534 float f;
535 inpixels = NULL;
539 if (!inpixels)
540 {
551 return;
552 }
556 r_refdef.fog_height_table2d = (unsigned char *)Mem_Alloc(r_main_mempool, size * size * 4);
559 // LadyHavoc: now the magic - what is that table2d for? it is a cooked
560 // average fog color table accounting for every fog layer between a point
561 // and the camera. (Note: attenuation is handled separately!)
562 for (y = 0;y < size;y++)
563 {
564 for (x = 0;x < size;x++)
565 {
566 Vector4Clear(c);
567 f = 0;
568 if (x < y)
569 {
570 for (j = x;j <= y;j++)
571 {
573 f++;
574 }
575 }
576 else
577 {
578 for (j = x;j >= y;j--)
579 {
581 f++;
582 }
583 }
584 f = 1.0f / f;
585 r_refdef.fog_height_table2d[(y*size+x)*4+0] = (unsigned char)(c[0] * f);
586 r_refdef.fog_height_table2d[(y*size+x)*4+1] = (unsigned char)(c[1] * f);
587 r_refdef.fog_height_table2d[(y*size+x)*4+2] = (unsigned char)(c[2] * f);
588 r_refdef.fog_height_table2d[(y*size+x)*4+3] = (unsigned char)(c[3] * f);
589 }
590 }
592}
593
594//=======================================================================================================================================================
595
596static const char *builtinshaderstrings[] =
597{
598#include "shader_glsl.h"
5990
600};
601
602//=======================================================================================================================================================
603
605{
606 const char *pretext;
607 const char *name;
608}
610
611typedef struct shadermodeinfo_s
612{
613 const char *sourcebasename;
614 const char *extension;
616 const char *pretext;
617 const char *name;
618 char *filename;
621}
623
624// NOTE: MUST MATCH ORDER OF SHADERPERMUTATION_* DEFINES!
626{
627 {"#define USEDIFFUSE\n", " diffuse"},
628 {"#define USEVERTEXTEXTUREBLEND\n", " vertextextureblend"},
629 {"#define USEVIEWTINT\n", " viewtint"},
630 {"#define USECOLORMAPPING\n", " colormapping"},
631 {"#define USESATURATION\n", " saturation"},
632 {"#define USEFOGINSIDE\n", " foginside"},
633 {"#define USEFOGOUTSIDE\n", " fogoutside"},
634 {"#define USEFOGHEIGHTTEXTURE\n", " fogheighttexture"},
635 {"#define USEFOGALPHAHACK\n", " fogalphahack"},
636 {"#define USEGAMMARAMPS\n", " gammaramps"},
637 {"#define USECUBEFILTER\n", " cubefilter"},
638 {"#define USEGLOW\n", " glow"},
639 {"#define USEBLOOM\n", " bloom"},
640 {"#define USESPECULAR\n", " specular"},
641 {"#define USEPOSTPROCESSING\n", " postprocessing"},
642 {"#define USEREFLECTION\n", " reflection"},
643 {"#define USEOFFSETMAPPING\n", " offsetmapping"},
644 {"#define USEOFFSETMAPPING_RELIEFMAPPING\n", " reliefmapping"},
645 {"#define USESHADOWMAP2D\n", " shadowmap2d"},
646 {"#define USESHADOWMAPVSDCT\n", " shadowmapvsdct"}, // TODO make this a static parm
647 {"#define USESHADOWMAPORTHO\n", " shadowmaportho"},
648 {"#define USEDEFERREDLIGHTMAP\n", " deferredlightmap"},
649 {"#define USEALPHAKILL\n", " alphakill"},
650 {"#define USEREFLECTCUBE\n", " reflectcube"},
651 {"#define USENORMALMAPSCROLLBLEND\n", " normalmapscrollblend"},
652 {"#define USEBOUNCEGRID\n", " bouncegrid"},
653 {"#define USEBOUNCEGRIDDIRECTIONAL\n", " bouncegriddirectional"}, // TODO make this a static parm
654 {"#define USETRIPPY\n", " trippy"},
655 {"#define USEDEPTHRGB\n", " depthrgb"},
656 {"#define USEALPHAGENVERTEX\n", " alphagenvertex"},
657 {"#define USESKELETAL\n", " skeletal"},
658 {"#define USEOCCLUDE\n", " occlude"}
659};
660
661// NOTE: MUST MATCH ORDER OF SHADERMODE_* ENUMS!
663{
664 // SHADERLANGUAGE_GLSL
665 {
666 {"combined", "glsl", builtinshaderstrings, "#define MODE_GENERIC\n", " generic"},
667 {"combined", "glsl", builtinshaderstrings, "#define MODE_POSTPROCESS\n", " postprocess"},
668 {"combined", "glsl", builtinshaderstrings, "#define MODE_DEPTH_OR_SHADOW\n", " depth/shadow"},
669 {"combined", "glsl", builtinshaderstrings, "#define MODE_FLATCOLOR\n", " flatcolor"},
670 {"combined", "glsl", builtinshaderstrings, "#define MODE_VERTEXCOLOR\n", " vertexcolor"},
671 {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTMAP\n", " lightmap"},
672 {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"},
673 {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"},
674 {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP\n", " lightdirectionmap_forced_lightmap"},
675 {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR\n", " lightdirectionmap_forced_vertexcolor"},
676 {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTGRID\n", " lightgrid"},
677 {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTDIRECTION\n", " lightdirection"},
678 {"combined", "glsl", builtinshaderstrings, "#define MODE_LIGHTSOURCE\n", " lightsource"},
679 {"combined", "glsl", builtinshaderstrings, "#define MODE_REFRACTION\n", " refraction"},
680 {"combined", "glsl", builtinshaderstrings, "#define MODE_WATER\n", " water"},
681 {"combined", "glsl", builtinshaderstrings, "#define MODE_DEFERREDGEOMETRY\n", " deferredgeometry"},
682 {"combined", "glsl", builtinshaderstrings, "#define MODE_DEFERREDLIGHTSOURCE\n", " deferredlightsource"},
683 },
684};
685
688{
691 unsigned int mode;
693
698 // texture units assigned to each detected uniform
825}
827
828#define SHADERPERMUTATION_HASHSIZE 256
829
830
831// non-degradable "lightweight" shader parameters to keep the permutations simpler
832// these can NOT degrade! only use for simple stuff
833enum
834{
841 SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS = 6, // use both alpha layers while blending materials, allows more advanced microblending
851#define SHADERSTATICPARMS_COUNT 15
852
855
856static unsigned int r_compileshader_staticparms[(SHADERSTATICPARMS_COUNT + 0x1F) >> 5] = {0};
857#define R_COMPILESHADER_STATICPARM_ENABLE(p) r_compileshader_staticparms[(p) >> 5] |= (1 << ((p) & 0x1F))
858
860extern int r_shadow_shadowmappcf;
862{
866
867 // detect all
875 {
884 }
885 if (r_fxaa.integer)
889
892 if (r_shadow_shadowmappcf > 1)
894 else if (r_shadow_shadowmappcf)
902
904}
905
906#define R_COMPILESHADER_STATICPARM_EMIT(p, n) \
907 if(r_compileshader_staticparms[(p) >> 5] & (1 << ((p) & 0x1F))) \
908 shaderstaticparmstrings_list[shaderstaticparms_count++] = "#define " n "\n"; \
909 else \
910 shaderstaticparmstrings_list[shaderstaticparms_count++] = "\n"
911static void R_CompileShader_AddStaticParms(unsigned int mode, uint64_t permutation)
912{
914
915 // emit all
931}
932
939
941{
942 //unsigned int hashdepth = 0;
943 unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1);
945 for (p = r_glsl_permutationhash[mode][hashindex];p;p = p->hashnext)
946 {
947 if (p->mode == mode && p->permutation == permutation)
948 {
949 //if (hashdepth > 10)
950 // Con_Printf("R_GLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
951 return p;
952 }
953 //hashdepth++;
954 }
956 p->mode = mode;
957 p->permutation = permutation;
960 //if (hashdepth > 10)
961 // Con_Printf("R_GLSL_FindPermutation: Warning: %i:%i has hashdepth %i\n", mode, permutation, hashdepth);
962 return p;
963}
964
965static char *R_ShaderStrCat(const char **strings)
966{
967 char *string, *s;
968 const char **p = strings;
969 const char *t;
970 size_t len = 0;
971 for (p = strings;(t = *p);p++)
972 len += strlen(t);
973 len++;
974 s = string = (char *)Mem_Alloc(r_main_mempool, len);
975 len = 0;
976 for (p = strings;(t = *p);p++)
977 {
978 len = strlen(t);
979 memcpy(s, t, len);
980 s += len;
981 }
982 *s = 0;
983 return string;
984}
985
986static char *R_ShaderStrCat(const char **strings);
987static void R_InitShaderModeInfo(void)
988{
989 int i, language;
991 // we have a bunch of things to compute that weren't calculated at engine compile time - all filenames should have a crc of the builtin strings to prevent accidental overrides (any customization must be updated to match engine)
993 {
994 for (i = 0; i < SHADERMODE_COUNT; i++)
995 {
996 char filename[MAX_QPATH];
998 modeinfo->builtinstring = R_ShaderStrCat(modeinfo->builtinshaderstrings);
999 modeinfo->builtincrc = CRC_Block((const unsigned char *)modeinfo->builtinstring, strlen(modeinfo->builtinstring));
1000 dpsnprintf(filename, sizeof(filename), "%s/%s_crc%i.%s", modeinfo->extension, modeinfo->sourcebasename, modeinfo->builtincrc, modeinfo->extension);
1001 modeinfo->filename = Mem_strdup(r_main_mempool, filename);
1002 }
1003 }
1004}
1005
1007{
1008 char *shaderstring;
1009 // if the mode has no filename we have to return the builtin string
1010 if (builtinonly || !modeinfo->filename)
1011 return Mem_strdup(r_main_mempool, modeinfo->builtinstring);
1012 // note that FS_LoadFile appends a 0 byte to make it a valid string
1013 shaderstring = (char *)FS_LoadFile(modeinfo->filename, r_main_mempool, false, NULL);
1014 if (shaderstring)
1015 {
1017 Con_DPrintf("Loading shaders from file %s...\n", modeinfo->filename);
1018 return shaderstring;
1019 }
1020 // fall back to builtinstring
1021 return Mem_strdup(r_main_mempool, modeinfo->builtinstring);
1022}
1023
1024static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode, uint64_t permutation)
1025{
1026 unsigned i;
1027 int ubibind;
1028 int sampler;
1030 char *sourcestring;
1031 char permutationname[256];
1032 int vertstrings_count = 0;
1033 int geomstrings_count = 0;
1034 int fragstrings_count = 0;
1035 const char *vertstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1036 const char *geomstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1037 const char *fragstrings_list[32+5+SHADERSTATICPARMS_COUNT+1];
1038
1039 if (p->compiled)
1040 return;
1041 p->compiled = true;
1042 p->program = 0;
1043
1044 permutationname[0] = 0;
1046
1048
1049 // we need 140 for r_glsl_skeletal (GL_ARB_uniform_buffer_object)
1050 if(vid.support.glshaderversion >= 140)
1051 {
1052 vertstrings_list[vertstrings_count++] = "#version 140\n";
1053 geomstrings_list[geomstrings_count++] = "#version 140\n";
1054 fragstrings_list[fragstrings_count++] = "#version 140\n";
1055 vertstrings_list[vertstrings_count++] = "#define GLSL140\n";
1056 geomstrings_list[geomstrings_count++] = "#define GLSL140\n";
1057 fragstrings_list[fragstrings_count++] = "#define GLSL140\n";
1058 }
1059 // if we can do #version 130, we should (this improves quality of offset/reliefmapping thanks to textureGrad)
1060 else if(vid.support.glshaderversion >= 130)
1061 {
1062 vertstrings_list[vertstrings_count++] = "#version 130\n";
1063 geomstrings_list[geomstrings_count++] = "#version 130\n";
1064 fragstrings_list[fragstrings_count++] = "#version 130\n";
1065 vertstrings_list[vertstrings_count++] = "#define GLSL130\n";
1066 geomstrings_list[geomstrings_count++] = "#define GLSL130\n";
1067 fragstrings_list[fragstrings_count++] = "#define GLSL130\n";
1068 }
1069 // if we can do #version 120, we should (this adds the invariant keyword)
1070 else if(vid.support.glshaderversion >= 120)
1071 {
1072 vertstrings_list[vertstrings_count++] = "#version 120\n";
1073 geomstrings_list[geomstrings_count++] = "#version 120\n";
1074 fragstrings_list[fragstrings_count++] = "#version 120\n";
1075 vertstrings_list[vertstrings_count++] = "#define GLSL120\n";
1076 geomstrings_list[geomstrings_count++] = "#define GLSL120\n";
1077 fragstrings_list[fragstrings_count++] = "#define GLSL120\n";
1078 }
1079 // GLES also adds several things from GLSL120
1080 switch(vid.renderpath)
1081 {
1082 case RENDERPATH_GLES2:
1083 vertstrings_list[vertstrings_count++] = "#define GLES\n";
1084 geomstrings_list[geomstrings_count++] = "#define GLES\n";
1085 fragstrings_list[fragstrings_count++] = "#define GLES\n";
1086 break;
1087 default:
1088 break;
1089 }
1090
1091 // the first pretext is which type of shader to compile as
1092 // (later these will all be bound together as a program object)
1093 vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
1094 geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
1095 fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
1096
1097 // the second pretext is the mode (for example a light source)
1102
1103 // now add all the permutation pretexts
1104 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1105 {
1106 if (permutation & (1ll<<i))
1107 {
1112 }
1113 else
1114 {
1115 // keep line numbers correct
1119 }
1120 }
1121
1122 // add static parms
1130
1131 // now append the shader text itself
1135
1136 // we don't currently use geometry shaders for anything, so just empty the list
1138
1139 // compile the shader program
1142 if (p->program)
1143 {
1146 // look up all the uniform variable names we care about, so we don't
1147 // have to look them up every time we set them
1148
1149#if 0
1150 // debugging aid
1151 {
1154 char uniformname[128];
1156 GLint uniformsize = 0;
1157 GLenum uniformtype = 0;
1158 memset(uniformname, 0, sizeof(uniformname));
1160 Con_Printf("Shader has %i uniforms\n", numactiveuniforms);
1162 {
1164 Con_Printf("Uniform %i name \"%s\" size %i type %i\n", (int)activeuniformindex, uniformname, (int)uniformsize, (int)uniformtype);
1165 }
1166 }
1167#endif
1168
1169 p->loc_Texture_First = qglGetUniformLocation(p->program, "Texture_First");
1170 p->loc_Texture_Second = qglGetUniformLocation(p->program, "Texture_Second");
1171 p->loc_Texture_GammaRamps = qglGetUniformLocation(p->program, "Texture_GammaRamps");
1172 p->loc_Texture_Normal = qglGetUniformLocation(p->program, "Texture_Normal");
1173 p->loc_Texture_Color = qglGetUniformLocation(p->program, "Texture_Color");
1174 p->loc_Texture_Gloss = qglGetUniformLocation(p->program, "Texture_Gloss");
1175 p->loc_Texture_Glow = qglGetUniformLocation(p->program, "Texture_Glow");
1176 p->loc_Texture_SecondaryNormal = qglGetUniformLocation(p->program, "Texture_SecondaryNormal");
1177 p->loc_Texture_SecondaryColor = qglGetUniformLocation(p->program, "Texture_SecondaryColor");
1178 p->loc_Texture_SecondaryGloss = qglGetUniformLocation(p->program, "Texture_SecondaryGloss");
1179 p->loc_Texture_SecondaryGlow = qglGetUniformLocation(p->program, "Texture_SecondaryGlow");
1180 p->loc_Texture_Pants = qglGetUniformLocation(p->program, "Texture_Pants");
1181 p->loc_Texture_Shirt = qglGetUniformLocation(p->program, "Texture_Shirt");
1182 p->loc_Texture_FogHeightTexture = qglGetUniformLocation(p->program, "Texture_FogHeightTexture");
1183 p->loc_Texture_FogMask = qglGetUniformLocation(p->program, "Texture_FogMask");
1184 p->loc_Texture_LightGrid = qglGetUniformLocation(p->program, "Texture_LightGrid");
1185 p->loc_Texture_Lightmap = qglGetUniformLocation(p->program, "Texture_Lightmap");
1186 p->loc_Texture_Deluxemap = qglGetUniformLocation(p->program, "Texture_Deluxemap");
1187 p->loc_Texture_Attenuation = qglGetUniformLocation(p->program, "Texture_Attenuation");
1188 p->loc_Texture_Cube = qglGetUniformLocation(p->program, "Texture_Cube");
1189 p->loc_Texture_Refraction = qglGetUniformLocation(p->program, "Texture_Refraction");
1190 p->loc_Texture_Reflection = qglGetUniformLocation(p->program, "Texture_Reflection");
1191 p->loc_Texture_ShadowMap2D = qglGetUniformLocation(p->program, "Texture_ShadowMap2D");
1192 p->loc_Texture_CubeProjection = qglGetUniformLocation(p->program, "Texture_CubeProjection");
1193 p->loc_Texture_ScreenNormalMap = qglGetUniformLocation(p->program, "Texture_ScreenNormalMap");
1194 p->loc_Texture_ScreenDiffuse = qglGetUniformLocation(p->program, "Texture_ScreenDiffuse");
1195 p->loc_Texture_ScreenSpecular = qglGetUniformLocation(p->program, "Texture_ScreenSpecular");
1196 p->loc_Texture_ReflectMask = qglGetUniformLocation(p->program, "Texture_ReflectMask");
1197 p->loc_Texture_ReflectCube = qglGetUniformLocation(p->program, "Texture_ReflectCube");
1198 p->loc_Texture_BounceGrid = qglGetUniformLocation(p->program, "Texture_BounceGrid");
1199 p->loc_Alpha = qglGetUniformLocation(p->program, "Alpha");
1200 p->loc_BloomBlur_Parameters = qglGetUniformLocation(p->program, "BloomBlur_Parameters");
1201 p->loc_ClientTime = qglGetUniformLocation(p->program, "ClientTime");
1202 p->loc_Color_Ambient = qglGetUniformLocation(p->program, "Color_Ambient");
1203 p->loc_Color_Diffuse = qglGetUniformLocation(p->program, "Color_Diffuse");
1204 p->loc_Color_Specular = qglGetUniformLocation(p->program, "Color_Specular");
1205 p->loc_Color_Glow = qglGetUniformLocation(p->program, "Color_Glow");
1206 p->loc_Color_Pants = qglGetUniformLocation(p->program, "Color_Pants");
1207 p->loc_Color_Shirt = qglGetUniformLocation(p->program, "Color_Shirt");
1208 p->loc_DeferredColor_Ambient = qglGetUniformLocation(p->program, "DeferredColor_Ambient");
1209 p->loc_DeferredColor_Diffuse = qglGetUniformLocation(p->program, "DeferredColor_Diffuse");
1210 p->loc_DeferredColor_Specular = qglGetUniformLocation(p->program, "DeferredColor_Specular");
1211 p->loc_DeferredMod_Diffuse = qglGetUniformLocation(p->program, "DeferredMod_Diffuse");
1212 p->loc_DeferredMod_Specular = qglGetUniformLocation(p->program, "DeferredMod_Specular");
1213 p->loc_DistortScaleRefractReflect = qglGetUniformLocation(p->program, "DistortScaleRefractReflect");
1214 p->loc_EyePosition = qglGetUniformLocation(p->program, "EyePosition");
1215 p->loc_FogColor = qglGetUniformLocation(p->program, "FogColor");
1216 p->loc_FogHeightFade = qglGetUniformLocation(p->program, "FogHeightFade");
1217 p->loc_FogPlane = qglGetUniformLocation(p->program, "FogPlane");
1218 p->loc_FogPlaneViewDist = qglGetUniformLocation(p->program, "FogPlaneViewDist");
1219 p->loc_FogRangeRecip = qglGetUniformLocation(p->program, "FogRangeRecip");
1220 p->loc_LightColor = qglGetUniformLocation(p->program, "LightColor");
1221 p->loc_LightGridMatrix = qglGetUniformLocation(p->program, "LightGridMatrix");
1222 p->loc_LightGridNormalMatrix = qglGetUniformLocation(p->program, "LightGridNormalMatrix");
1223 p->loc_LightDir = qglGetUniformLocation(p->program, "LightDir");
1224 p->loc_LightPosition = qglGetUniformLocation(p->program, "LightPosition");
1225 p->loc_OffsetMapping_ScaleSteps = qglGetUniformLocation(p->program, "OffsetMapping_ScaleSteps");
1226 p->loc_OffsetMapping_LodDistance = qglGetUniformLocation(p->program, "OffsetMapping_LodDistance");
1227 p->loc_OffsetMapping_Bias = qglGetUniformLocation(p->program, "OffsetMapping_Bias");
1228 p->loc_PixelSize = qglGetUniformLocation(p->program, "PixelSize");
1229 p->loc_ReflectColor = qglGetUniformLocation(p->program, "ReflectColor");
1230 p->loc_ReflectFactor = qglGetUniformLocation(p->program, "ReflectFactor");
1231 p->loc_ReflectOffset = qglGetUniformLocation(p->program, "ReflectOffset");
1232 p->loc_RefractColor = qglGetUniformLocation(p->program, "RefractColor");
1233 p->loc_Saturation = qglGetUniformLocation(p->program, "Saturation");
1234 p->loc_ScreenCenterRefractReflect = qglGetUniformLocation(p->program, "ScreenCenterRefractReflect");
1235 p->loc_ScreenScaleRefractReflect = qglGetUniformLocation(p->program, "ScreenScaleRefractReflect");
1236 p->loc_ScreenToDepth = qglGetUniformLocation(p->program, "ScreenToDepth");
1237 p->loc_ShadowMap_Parameters = qglGetUniformLocation(p->program, "ShadowMap_Parameters");
1238 p->loc_ShadowMap_TextureScale = qglGetUniformLocation(p->program, "ShadowMap_TextureScale");
1239 p->loc_SpecularPower = qglGetUniformLocation(p->program, "SpecularPower");
1240 p->loc_UserVec1 = qglGetUniformLocation(p->program, "UserVec1");
1241 p->loc_UserVec2 = qglGetUniformLocation(p->program, "UserVec2");
1242 p->loc_UserVec3 = qglGetUniformLocation(p->program, "UserVec3");
1243 p->loc_UserVec4 = qglGetUniformLocation(p->program, "UserVec4");
1244 p->loc_ColorFringe = qglGetUniformLocation(p->program, "ColorFringe");
1245 p->loc_ViewTintColor = qglGetUniformLocation(p->program, "ViewTintColor");
1246 p->loc_ViewToLight = qglGetUniformLocation(p->program, "ViewToLight");
1247 p->loc_ModelToLight = qglGetUniformLocation(p->program, "ModelToLight");
1248 p->loc_TexMatrix = qglGetUniformLocation(p->program, "TexMatrix");
1249 p->loc_BackgroundTexMatrix = qglGetUniformLocation(p->program, "BackgroundTexMatrix");
1250 p->loc_ModelViewMatrix = qglGetUniformLocation(p->program, "ModelViewMatrix");
1251 p->loc_ModelViewProjectionMatrix = qglGetUniformLocation(p->program, "ModelViewProjectionMatrix");
1252 p->loc_PixelToScreenTexCoord = qglGetUniformLocation(p->program, "PixelToScreenTexCoord");
1253 p->loc_ModelToReflectCube = qglGetUniformLocation(p->program, "ModelToReflectCube");
1254 p->loc_ShadowMapMatrix = qglGetUniformLocation(p->program, "ShadowMapMatrix");
1255 p->loc_BloomColorSubtract = qglGetUniformLocation(p->program, "BloomColorSubtract");
1256 p->loc_NormalmapScrollBlend = qglGetUniformLocation(p->program, "NormalmapScrollBlend");
1257 p->loc_BounceGridMatrix = qglGetUniformLocation(p->program, "BounceGridMatrix");
1258 p->loc_BounceGridIntensity = qglGetUniformLocation(p->program, "BounceGridIntensity");
1259 // initialize the samplers to refer to the texture units we use
1260 p->tex_Texture_First = -1;
1261 p->tex_Texture_Second = -1;
1262 p->tex_Texture_GammaRamps = -1;
1263 p->tex_Texture_Normal = -1;
1264 p->tex_Texture_Color = -1;
1265 p->tex_Texture_Gloss = -1;
1266 p->tex_Texture_Glow = -1;
1271 p->tex_Texture_Pants = -1;
1272 p->tex_Texture_Shirt = -1;
1274 p->tex_Texture_FogMask = -1;
1275 p->tex_Texture_LightGrid = -1;
1276 p->tex_Texture_Lightmap = -1;
1277 p->tex_Texture_Deluxemap = -1;
1279 p->tex_Texture_Cube = -1;
1280 p->tex_Texture_Refraction = -1;
1281 p->tex_Texture_Reflection = -1;
1289 p->tex_Texture_BounceGrid = -1;
1290 // bind the texture samplers in use
1291 sampler = 0;
1322 // get the uniform block indices so we can bind them
1324#ifndef USE_GLES2 /* FIXME: GLES3 only */
1325 p->ubiloc_Skeletal_Transform12_UniformBlock = qglGetUniformBlockIndex(p->program, "Skeletal_Transform12_UniformBlock");
1326#endif
1327 // clear the uniform block bindings
1329 // bind the uniform blocks in use
1330 ubibind = 0;
1331#ifndef USE_GLES2 /* FIXME: GLES3 only */
1333#endif
1334 // we're done compiling and setting up the shader, at least until it is used
1336 Con_DPrintf("^5GLSL shader %s compiled (%i textures).\n", permutationname, sampler);
1337 }
1338 else
1339 Con_Printf("^1GLSL shader %s failed! some features may not work properly.\n", permutationname);
1340
1341 // free the strings
1342 if (sourcestring)
1344}
1345
1346static void R_SetupShader_SetPermutationGLSL(unsigned int mode, uint64_t permutation)
1347{
1349 if (r_glsl_permutation != perm)
1350 {
1353 {
1355 {
1356 Con_DPrintf("Compiling shader mode %u permutation %" PRIx64 "\n", mode, permutation);
1357 R_GLSL_CompilePermutation(perm, mode, permutation);
1358 }
1360 {
1361 // remove features until we find a valid permutation
1362 unsigned i;
1363 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1364 {
1365 // reduce i more quickly whenever it would not remove any bits
1367 if (!(permutation & j))
1368 continue;
1369 permutation -= j;
1372 R_GLSL_CompilePermutation(perm, mode, permutation);
1374 break;
1375 }
1377 {
1378 //Con_Printf("Could not find a working OpenGL 2.0 shader for permutation %s %s\n", shadermodeinfo[mode].filename, shadermodeinfo[mode].pretext);
1381 return; // no bit left to clear, entire mode is broken
1382 }
1383 }
1384 }
1387 }
1392}
1393
1395{
1396 unsigned int i, limit;
1397 switch(vid.renderpath)
1398 {
1399 case RENDERPATH_GL32:
1400 case RENDERPATH_GLES2:
1401 {
1405 for (i = 0;i < limit;i++)
1406 {
1408 {
1411 }
1412 }
1414 }
1415 break;
1416 }
1417}
1418
1420{
1421 unsigned i;
1422 int language, mode, dupe;
1423 char *text;
1425 qfile_t *file;
1426
1428 {
1430 for (mode = 0;mode < SHADERMODE_COUNT;mode++)
1431 {
1432 // don't dump the same file multiple times (most or all shaders come from the same file)
1433 for (dupe = mode - 1;dupe >= 0;dupe--)
1434 if (!strcmp(modeinfo[mode].filename, modeinfo[dupe].filename))
1435 break;
1436 if (dupe >= 0)
1437 continue;
1438 text = modeinfo[mode].builtinstring;
1439 if (!text)
1440 continue;
1441 file = FS_OpenRealFile(modeinfo[mode].filename, "w", false);
1442 if (file)
1443 {
1444 FS_Print(file, "/* The engine may define the following macros:\n");
1445 FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n");
1446 for (i = 0;i < SHADERMODE_COUNT;i++)
1447 FS_Print(file, modeinfo[i].pretext);
1448 for (i = 0;i < SHADERPERMUTATION_COUNT;i++)
1449 FS_Print(file, shaderpermutationinfo[i].pretext);
1450 FS_Print(file, "*/\n");
1451 FS_Print(file, text);
1452 FS_Close(file);
1453 Con_Printf("%s written\n", modeinfo[mode].filename);
1454 }
1455 else
1456 Con_Printf(CON_ERROR "failed to write to %s\n", modeinfo[mode].filename);
1457 }
1458 }
1459}
1460
1487
1492
1516
1517#define BLENDFUNC_ALLOWS_COLORMOD 1
1518#define BLENDFUNC_ALLOWS_FOG 2
1519#define BLENDFUNC_ALLOWS_FOG_HACK0 4
1520#define BLENDFUNC_ALLOWS_FOG_HACKALPHA 8
1521#define BLENDFUNC_ALLOWS_ANYFOG (BLENDFUNC_ALLOWS_FOG | BLENDFUNC_ALLOWS_FOG_HACK0 | BLENDFUNC_ALLOWS_FOG_HACKALPHA)
1522static int R_BlendFuncFlags(int src, int dst)
1523{
1524 int r = 0;
1525
1526 // a blendfunc allows colormod if:
1527 // a) it can never keep the destination pixel invariant, or
1528 // b) it can keep the destination pixel invariant, and still can do so if colormodded
1529 // this is to prevent unintended side effects from colormod
1530
1531 // a blendfunc allows fog if:
1532 // blend(fog(src), fog(dst)) == fog(blend(src, dst))
1533 // this is to prevent unintended side effects from fog
1534
1535 // these checks are the output of fogeval.pl
1536
1545 if(src == GL_ONE && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG_HACK0;
1547 if(src == GL_ONE && dst == GL_ZERO) r |= BLENDFUNC_ALLOWS_FOG;
1557 if(src == GL_ZERO && dst == GL_ONE) r |= BLENDFUNC_ALLOWS_FOG;
1559
1560 return r;
1561}
1562
1564{
1565 // select a permutation of the lighting shader appropriate to this
1566 // combination of texture, entity, light source, and fogging, only use the
1567 // minimum features necessary to avoid wasting rendering time in the
1568 // fragment shader on features that are not being used
1569 uint64_t permutation = 0;
1570 unsigned int mode = 0;
1571 int blendfuncflags;
1573 float m16f[16];
1576 if (r_trippy.integer && !notrippy)
1577 permutation |= SHADERPERMUTATION_TRIPPY;
1579 permutation |= SHADERPERMUTATION_ALPHAKILL;
1581 permutation |= SHADERPERMUTATION_OCCLUDE;
1582 if (t->r_water_waterscroll[0] && t->r_water_waterscroll[1])
1583 permutation |= SHADERPERMUTATION_NORMALMAPSCROLLBLEND; // todo: make generic
1585 {
1586 // distorted background
1588 {
1591 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
1593 {
1594 // this is the right thing to do for wateralpha
1597 }
1598 else
1599 {
1600 // this is the right thing to do for entity alpha
1603 }
1604 }
1606 {
1609 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
1612 }
1613 else
1614 {
1619 }
1621 GL_AlphaToCoverage(false);
1622 }
1624 {
1626 {
1627 switch(t->offsetmapping)
1628 {
1629 case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
1632 case OFFSETMAPPING_OFF: break;
1633 }
1634 }
1637 // normalmap (deferred prepass), may use alpha test on diffuse
1642 GL_AlphaToCoverage(false);
1643 }
1644 else if (rsurfacepass == RSURFPASS_RTLIGHT)
1645 {
1647 {
1648 switch(t->offsetmapping)
1649 {
1650 case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
1653 case OFFSETMAPPING_OFF: break;
1654 }
1655 }
1659 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
1660 // light source
1663 permutation |= SHADERPERMUTATION_CUBEFILTER;
1665 permutation |= SHADERPERMUTATION_DIFFUSE;
1668 if (r_refdef.fogenabled)
1670 if (t->colormapping)
1671 permutation |= SHADERPERMUTATION_COLORMAPPING;
1673 {
1674 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
1676 permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
1677
1679 permutation |= SHADERPERMUTATION_DEPTHRGB;
1680 }
1681 if (t->reflectmasktexture)
1682 permutation |= SHADERPERMUTATION_REFLECTCUBE;
1686 GL_AlphaToCoverage(false);
1687 }
1689 {
1691 {
1692 switch(t->offsetmapping)
1693 {
1694 case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
1697 case OFFSETMAPPING_OFF: break;
1698 }
1699 }
1703 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
1704 // directional model lighting
1707 permutation |= SHADERPERMUTATION_GLOW;
1708 permutation |= SHADERPERMUTATION_DIFFUSE;
1710 permutation |= SHADERPERMUTATION_SPECULAR;
1711 if (r_refdef.fogenabled)
1713 if (t->colormapping)
1714 permutation |= SHADERPERMUTATION_COLORMAPPING;
1716 {
1717 permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
1718 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
1719
1721 permutation |= SHADERPERMUTATION_DEPTHRGB;
1722 }
1724 permutation |= SHADERPERMUTATION_REFLECTION;
1727 if (t->reflectmasktexture)
1728 permutation |= SHADERPERMUTATION_REFLECTCUBE;
1730 {
1731 permutation |= SHADERPERMUTATION_BOUNCEGRID;
1734 }
1737 // when using alphatocoverage, we don't need alphakill
1739 {
1741 {
1743 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
1744 }
1745 else
1746 GL_AlphaToCoverage(false);
1747 }
1748 }
1750 {
1752 {
1753 switch(t->offsetmapping)
1754 {
1755 case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
1758 case OFFSETMAPPING_OFF: break;
1759 }
1760 }
1764 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
1765 // directional model lighting
1768 permutation |= SHADERPERMUTATION_GLOW;
1770 permutation |= SHADERPERMUTATION_DIFFUSE;
1772 permutation |= SHADERPERMUTATION_SPECULAR;
1773 if (r_refdef.fogenabled)
1775 if (t->colormapping)
1776 permutation |= SHADERPERMUTATION_COLORMAPPING;
1778 {
1779 permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
1780 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
1781
1783 permutation |= SHADERPERMUTATION_DEPTHRGB;
1784 }
1786 permutation |= SHADERPERMUTATION_REFLECTION;
1789 if (t->reflectmasktexture)
1790 permutation |= SHADERPERMUTATION_REFLECTCUBE;
1792 {
1793 permutation |= SHADERPERMUTATION_BOUNCEGRID;
1796 }
1799 // when using alphatocoverage, we don't need alphakill
1801 {
1803 {
1805 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
1806 }
1807 else
1808 GL_AlphaToCoverage(false);
1809 }
1810 }
1811 else
1812 {
1814 {
1815 switch(t->offsetmapping)
1816 {
1817 case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break;
1820 case OFFSETMAPPING_OFF: break;
1821 }
1822 }
1826 permutation |= SHADERPERMUTATION_ALPHAGEN_VERTEX;
1827 // lightmapped wall
1829 permutation |= SHADERPERMUTATION_GLOW;
1830 if (r_refdef.fogenabled && !ui)
1832 if (t->colormapping)
1833 permutation |= SHADERPERMUTATION_COLORMAPPING;
1835 {
1836 permutation |= SHADERPERMUTATION_SHADOWMAPORTHO;
1837 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
1838
1840 permutation |= SHADERPERMUTATION_DEPTHRGB;
1841 }
1843 permutation |= SHADERPERMUTATION_REFLECTION;
1846 if (t->reflectmasktexture)
1847 permutation |= SHADERPERMUTATION_REFLECTCUBE;
1849 {
1850 // deluxemapping (light direction texture)
1853 else
1855 permutation |= SHADERPERMUTATION_DIFFUSE;
1858 }
1859 else if (r_glsl_deluxemapping.integer >= 2)
1860 {
1861 // fake deluxemapping (uniform light direction in tangentspace)
1864 else
1866 permutation |= SHADERPERMUTATION_DIFFUSE;
1869 }
1871 {
1872 // ordinary lightmapping (q1bsp, q3bsp)
1874 }
1875 else
1876 {
1877 // ordinary vertex coloring (q3bsp)
1879 }
1881 {
1882 permutation |= SHADERPERMUTATION_BOUNCEGRID;
1885 }
1888 // when using alphatocoverage, we don't need alphakill
1890 {
1892 {
1894 permutation &= ~SHADERPERMUTATION_ALPHAKILL;
1895 }
1896 else
1897 GL_AlphaToCoverage(false);
1898 }
1899 }
1903 permutation |= SHADERPERMUTATION_FOGALPHAHACK;
1904 switch(vid.renderpath)
1905 {
1906 case RENDERPATH_GL32:
1907 case RENDERPATH_GLES2:
1910 // this has to be after RSurf_PrepareVerticesForBatch
1912 permutation |= SHADERPERMUTATION_SKELETAL;
1914#ifndef USE_GLES2 /* FIXME: GLES3 only */
1916#endif
1919 {
1923 if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Ambient, rtlightambient[0], rtlightambient[1], rtlightambient[2]);
1926
1927 // additive passes are only darkened by fog, not tinted
1931 }
1932 else
1933 {
1935 {
1937 }
1938 else if (mode == SHADERMODE_LIGHTGRID)
1939 {
1943 // other LightGrid uniforms handled below
1944 }
1945 else if (mode == SHADERMODE_LIGHTDIRECTION)
1946 {
1954 }
1955 else
1956 {
1962 }
1963 // additive passes are only darkened by fog, not tinted
1964 if (r_glsl_permutation->loc_FogColor >= 0 && !ui)
1965 {
1968 else
1970 }
1980 }
1984 if (permutation & SHADERPERMUTATION_SHADOWMAPORTHO)
1985 {
1988 }
1989 else
1990 {
1993 }
1994
1999 {
2000 if (t->pantstexture)
2002 else
2004 }
2006 {
2007 if (t->shirttexture)
2009 else
2011 }
2021 );
2029 {
2030 float m9f[9];
2036 m9f[0] = m16f[0];m9f[1] = m16f[1];m9f[2] = m16f[2];
2037 m9f[3] = m16f[4];m9f[4] = m16f[5];m9f[5] = m16f[6];
2038 m9f[6] = m16f[8];m9f[7] = m16f[9];m9f[8] = m16f[10];
2040 }
2041
2063 {
2067 }
2068 else
2069 {
2071 }
2076 {
2078 if (rsurface.rtlight)
2079 {
2082 }
2083 }
2087 break;
2088 }
2089}
2090
2092{
2093 // select a permutation of the lighting shader appropriate to this
2094 // combination of texture, entity, light source, and fogging, only use the
2095 // minimum features necessary to avoid wasting rendering time in the
2096 // fragment shader on features that are not being used
2097 uint64_t permutation = 0;
2098 unsigned int mode = 0;
2099 const float *lightcolorbase = rtlight->currentcolor;
2100 float ambientscale = rtlight->ambientscale;
2101 float diffusescale = rtlight->diffusescale;
2102 float specularscale = rtlight->specularscale;
2103 // this is the location of the light in view space
2105 // this transforms from view space (camera) to light space (cubemap)
2108 float viewtolight16f[16];
2109 // light source
2111 if (rtlight->currentcubemap != r_texture_whitecube)
2112 permutation |= SHADERPERMUTATION_CUBEFILTER;
2113 if (diffusescale > 0)
2114 permutation |= SHADERPERMUTATION_DIFFUSE;
2115 if (specularscale > 0 && r_shadow_gloss.integer > 0)
2118 {
2119 permutation |= SHADERPERMUTATION_SHADOWMAP2D;
2121 permutation |= SHADERPERMUTATION_SHADOWMAPVSDCT;
2122
2124 permutation |= SHADERPERMUTATION_DEPTHRGB;
2125 }
2127 GL_AlphaToCoverage(false);
2132 switch(vid.renderpath)
2133 {
2134 case RENDERPATH_GL32:
2135 case RENDERPATH_GLES2:
2147
2153 break;
2154 }
2155}
2156
2157#define SKINFRAME_HASH 1024
2158
2159typedef struct
2160{
2161 unsigned int loadsequence; // incremented each level change
2164}
2167
2169{
2171 // wrap it without hitting zero
2172 if (r_skinframe.loadsequence >= 200)
2174}
2175
2177{
2178 if (!skinframe)
2179 return;
2180 // mark the skinframe as used for the purging code
2182}
2183
2185{
2186 if (s == NULL)
2187 return;
2188 if (s->merged == s->base)
2189 s->merged = NULL;
2190 R_PurgeTexture(s->stain); s->stain = NULL;
2191 R_PurgeTexture(s->merged); s->merged = NULL;
2192 R_PurgeTexture(s->base); s->base = NULL;
2193 R_PurgeTexture(s->pants); s->pants = NULL;
2194 R_PurgeTexture(s->shirt); s->shirt = NULL;
2195 R_PurgeTexture(s->nmap); s->nmap = NULL;
2196 R_PurgeTexture(s->gloss); s->gloss = NULL;
2197 R_PurgeTexture(s->glow); s->glow = NULL;
2198 R_PurgeTexture(s->fog); s->fog = NULL;
2200 s->loadsequence = 0;
2201}
2202
2204{
2205 int i;
2206 skinframe_t *s;
2207 for (i = 0;i < SKINFRAME_HASH;i++)
2208 {
2209 for (s = r_skinframe.hash[i];s;s = s->next)
2210 {
2213 }
2214 }
2215}
2216
2219 char basename[MAX_QPATH];
2220
2221 Image_StripImageExtension(name, basename, sizeof(basename));
2222
2223 if( last == NULL ) {
2224 int hashindex;
2225 hashindex = CRC_Block((unsigned char *)basename, strlen(basename)) & (SKINFRAME_HASH - 1);
2227 } else {
2228 item = last->next;
2229 }
2230
2231 // linearly search through the hash bucket
2232 for( ; item ; item = item->next ) {
2233 if( !strcmp( item->basename, basename ) ) {
2234 return item;
2235 }
2236 }
2237 return NULL;
2238}
2239
2240skinframe_t *R_SkinFrame_Find(const char *name, int textureflags, int comparewidth, int compareheight, int comparecrc, qbool add)
2241{
2243 int compareflags = textureflags & TEXF_IMPORTANTBITS;
2244 int hashindex;
2245 char basename[MAX_QPATH];
2246
2247 Image_StripImageExtension(name, basename, sizeof(basename));
2248
2249 hashindex = CRC_Block((unsigned char *)basename, strlen(basename)) & (SKINFRAME_HASH - 1);
2250 for (item = r_skinframe.hash[hashindex];item;item = item->next)
2251 if (!strcmp(item->basename, basename) &&
2252 item->textureflags == compareflags &&
2253 item->comparewidth == comparewidth &&
2254 item->compareheight == compareheight &&
2255 item->comparecrc == comparecrc)
2256 break;
2257
2258 if (!item)
2259 {
2260 if (!add)
2261 return NULL;
2263 memset(item, 0, sizeof(*item));
2264 dp_strlcpy(item->basename, basename, sizeof(item->basename));
2265 item->textureflags = compareflags;
2266 item->comparewidth = comparewidth;
2267 item->compareheight = compareheight;
2268 item->comparecrc = comparecrc;
2269 item->next = r_skinframe.hash[hashindex];
2271 }
2272 else if (textureflags & TEXF_FORCE_RELOAD)
2274
2276 return item;
2277}
2278
2279#define R_SKINFRAME_LOAD_AVERAGE_COLORS(cnt, getpixel) \
2280 { \
2281 unsigned long long avgcolor[5], wsum; \
2282 int pix, comp, w; \
2283 avgcolor[0] = 0; \
2284 avgcolor[1] = 0; \
2285 avgcolor[2] = 0; \
2286 avgcolor[3] = 0; \
2287 avgcolor[4] = 0; \
2288 wsum = 0; \
2289 for(pix = 0; pix < cnt; ++pix) \
2290 { \
2291 w = 0; \
2292 for(comp = 0; comp < 3; ++comp) \
2293 w += getpixel; \
2294 if(w) /* ignore perfectly black pixels because that is better for model skins */ \
2295 { \
2296 ++wsum; \
2297 /* comp = 3; -- not needed, comp is always 3 when we get here */ \
2298 w = getpixel; \
2299 for(comp = 0; comp < 3; ++comp) \
2300 avgcolor[comp] += getpixel * w; \
2301 avgcolor[3] += w; \
2302 } \
2303 /* comp = 3; -- not needed, comp is always 3 when we get here */ \
2304 avgcolor[4] += getpixel; \
2305 } \
2306 if(avgcolor[3] == 0) /* no pixels seen? even worse */ \
2307 avgcolor[3] = 1; \
2308 skinframe->avgcolor[0] = avgcolor[2] / (255.0 * avgcolor[3]); \
2309 skinframe->avgcolor[1] = avgcolor[1] / (255.0 * avgcolor[3]); \
2310 skinframe->avgcolor[2] = avgcolor[0] / (255.0 * avgcolor[3]); \
2311 skinframe->avgcolor[3] = avgcolor[4] / (255.0 * cnt); \
2312 }
2313
2315{
2316 skinframe_t *skinframe;
2317
2318 if (cls.state == ca_dedicated)
2319 return NULL;
2320
2321 // return an existing skinframe if already loaded
2322 skinframe = R_SkinFrame_Find(name, textureflags, 0, 0, 0, false);
2323 if (skinframe && skinframe->base)
2324 return skinframe;
2325
2326 // if the skinframe doesn't exist this will create it
2327 return R_SkinFrame_LoadExternal_SkinFrame(skinframe, name, textureflags, complain, fallbacknotexture);
2328}
2329
2330extern cvar_t gl_picmip;
2332{
2333 int j;
2334 unsigned char *pixels;
2335 unsigned char *bumppixels;
2336 unsigned char *basepixels = NULL;
2337 int basepixels_width = 0;
2338 int basepixels_height = 0;
2340 qbool ddshasalpha = false;
2341 float ddsavgcolor[4];
2342 char basename[MAX_QPATH];
2343 int miplevel = R_PicmipForFlags(textureflags);
2344 int savemiplevel = miplevel;
2345 int mymiplevel;
2346 char vabuf[1024];
2347
2348 if (cls.state == ca_dedicated)
2349 return NULL;
2350
2351 Image_StripImageExtension(name, basename, sizeof(basename));
2352
2353 // check for DDS texture file first
2354 if (!r_loaddds || !(ddsbase = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s.dds", basename), vid.sRGB3D, textureflags, &ddshasalpha, ddsavgcolor, miplevel, false)))
2355 {
2356 basepixels = loadimagepixelsbgra(name, complain, true, false, &miplevel);
2359 if (basepixels == NULL)
2360 return NULL;
2361 }
2362
2363 // FIXME handle miplevel
2364
2366 Con_Printf("loading skin \"%s\"\n", name);
2367
2368 // we've got some pixels to store, so really allocate this new texture now
2369 if (!skinframe)
2370 skinframe = R_SkinFrame_Find(name, textureflags, 0, 0, 0, true);
2371 textureflags &= ~TEXF_FORCE_RELOAD;
2372 skinframe->stain = NULL;
2373 skinframe->merged = NULL;
2374 skinframe->base = NULL;
2375 skinframe->pants = NULL;
2376 skinframe->shirt = NULL;
2377 skinframe->nmap = NULL;
2378 skinframe->gloss = NULL;
2379 skinframe->glow = NULL;
2380 skinframe->fog = NULL;
2381 skinframe->reflect = NULL;
2382 skinframe->hasalpha = false;
2383 // we could store the q2animname here too
2384
2385 if (ddsbase)
2386 {
2387 skinframe->base = ddsbase;
2388 skinframe->hasalpha = ddshasalpha;
2389 VectorCopy(ddsavgcolor, skinframe->avgcolor);
2390 if (r_loadfog && skinframe->hasalpha)
2391 skinframe->fog = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_mask.dds", skinframe->basename), false, textureflags | TEXF_ALPHA, NULL, NULL, miplevel, true);
2392 //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]);
2393 }
2394 else
2395 {
2399 if (textureflags & TEXF_ALPHA)
2400 {
2401 for (j = 3;j < basepixels_width * basepixels_height * 4;j += 4)
2402 {
2403 if (basepixels[j] < 255)
2404 {
2405 skinframe->hasalpha = true;
2406 break;
2407 }
2408 }
2409 if (r_loadfog && skinframe->hasalpha)
2410 {
2411 // has transparent pixels
2412 pixels = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4);
2413 for (j = 0;j < image_width * image_height * 4;j += 4)
2414 {
2415 pixels[j+0] = 255;
2416 pixels[j+1] = 255;
2417 pixels[j+2] = 255;
2418 pixels[j+3] = basepixels[j+3];
2419 }
2422 }
2423 }
2425#ifndef USE_GLES2
2426 //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]);
2427 if (r_savedds && skinframe->base)
2428 R_SaveTextureDDSFile(skinframe->base, va(vabuf, sizeof(vabuf), "dds/%s.dds", skinframe->basename), r_texture_dds_save.integer < 2, skinframe->hasalpha);
2429 if (r_savedds && skinframe->fog)
2430 R_SaveTextureDDSFile(skinframe->fog, va(vabuf, sizeof(vabuf), "dds/%s_mask.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
2431#endif
2432 }
2433
2434 if (r_loaddds)
2435 {
2437 if (r_loadnormalmap)
2438 skinframe->nmap = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_norm.dds", skinframe->basename), false, (TEXF_ALPHA | textureflags) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), NULL, NULL, mymiplevel, true);
2439 skinframe->glow = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_glow.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel, true);
2440 if (r_loadgloss)
2441 skinframe->gloss = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_gloss.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel, true);
2442 skinframe->pants = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_pants.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel, true);
2443 skinframe->shirt = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_shirt.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel, true);
2444 skinframe->reflect = R_LoadTextureDDSFile(r_main_texturepool, va(vabuf, sizeof(vabuf), "dds/%s_reflect.dds", skinframe->basename), vid.sRGB3D, textureflags, NULL, NULL, mymiplevel, true);
2445 }
2446
2447 // _norm is the name used by tenebrae and has been adopted as standard
2448 if (r_loadnormalmap && skinframe->nmap == NULL)
2449 {
2451 if ((pixels = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "%s_norm", skinframe->basename), false, false, false, &mymiplevel)) != NULL)
2452 {
2455 pixels = NULL;
2456 }
2457 else if (r_shadow_bumpscale_bumpmap.value > 0 && (bumppixels = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "%s_bump", skinframe->basename), false, false, false, &mymiplevel)) != NULL)
2458 {
2459 pixels = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4);
2464 }
2466 {
2471 }
2472#ifndef USE_GLES2
2473 if (r_savedds && skinframe->nmap)
2474 R_SaveTextureDDSFile(skinframe->nmap, va(vabuf, sizeof(vabuf), "dds/%s_norm.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
2475#endif
2476 }
2477
2478 // _luma is supported only for tenebrae compatibility
2479 // _blend and .blend are supported only for Q3 & QL compatibility, this hack can be removed if better Q3 shader support is implemented
2480 // _glow is the preferred name
2482 if (skinframe->glow == NULL && ((pixels = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "%s_glow", skinframe->basename), false, false, false, &mymiplevel)) || (pixels = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "%s.blend", skinframe->basename), false, false, false, &mymiplevel)) || (pixels = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "%s_blend", skinframe->basename), false, false, false, &mymiplevel)) || (pixels = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "%s_luma", skinframe->basename), false, false, false, &mymiplevel))))
2483 {
2485#ifndef USE_GLES2
2486 if (r_savedds && skinframe->glow)
2487 R_SaveTextureDDSFile(skinframe->glow, va(vabuf, sizeof(vabuf), "dds/%s_glow.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
2488#endif
2490 }
2491
2493 if (skinframe->gloss == NULL && r_loadgloss && (pixels = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "%s_gloss", skinframe->basename), false, false, false, &mymiplevel)))
2494 {
2496#ifndef USE_GLES2
2497 if (r_savedds && skinframe->gloss)
2498 R_SaveTextureDDSFile(skinframe->gloss, va(vabuf, sizeof(vabuf), "dds/%s_gloss.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
2499#endif
2501 pixels = NULL;
2502 }
2503
2505 if (skinframe->pants == NULL && (pixels = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "%s_pants", skinframe->basename), false, false, false, &mymiplevel)))
2506 {
2508#ifndef USE_GLES2
2509 if (r_savedds && skinframe->pants)
2510 R_SaveTextureDDSFile(skinframe->pants, va(vabuf, sizeof(vabuf), "dds/%s_pants.dds", skinframe->basename), r_texture_dds_save.integer < 2, false);
2511#endif
2513 pixels = NULL;
2514 }
2515
2517 if (skinframe->shirt == NULL && (pixels = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "%s_shirt", skinframe->basename), false, false, false, &mymiplevel)))
2518 {
2520#ifndef USE_GLES2
2521 if (r_savedds && skinframe->shirt)
2522 R_SaveTextureDDSFile(skinframe->shirt, va(vabuf, sizeof(vabuf), "dds/%s_shirt.dds", skinframe->basename), r_texture_dds_save.integer < 2, false);
2523#endif
2525 pixels = NULL;
2526 }
2527
2529 if (skinframe->reflect == NULL && (pixels = loadimagepixelsbgra(va(vabuf, sizeof(vabuf), "%s_reflect", skinframe->basename), false, false, false, &mymiplevel)))
2530 {
2532#ifndef USE_GLES2
2533 if (r_savedds && skinframe->reflect)
2534 R_SaveTextureDDSFile(skinframe->reflect, va(vabuf, sizeof(vabuf), "dds/%s_reflect.dds", skinframe->basename), r_texture_dds_save.integer < 2, true);
2535#endif
2537 pixels = NULL;
2538 }
2539
2540 if (basepixels)
2542
2543 return skinframe;
2544}
2545
2546skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, const unsigned char *skindata, int width, int height, int comparewidth, int compareheight, int comparecrc, qbool sRGB)
2547{
2548 int i;
2549 skinframe_t *skinframe;
2550 char vabuf[1024];
2551
2552 if (cls.state == ca_dedicated)
2553 return NULL;
2554
2555 // if already loaded just return it, otherwise make a new skinframe
2556 skinframe = R_SkinFrame_Find(name, textureflags, comparewidth, compareheight, comparecrc, true);
2557 if (skinframe->base)
2558 return skinframe;
2559 textureflags &= ~TEXF_FORCE_RELOAD;
2560
2561 skinframe->stain = NULL;
2562 skinframe->merged = NULL;
2563 skinframe->base = NULL;
2564 skinframe->pants = NULL;
2565 skinframe->shirt = NULL;
2566 skinframe->nmap = NULL;
2567 skinframe->gloss = NULL;
2568 skinframe->glow = NULL;
2569 skinframe->fog = NULL;
2570 skinframe->reflect = NULL;
2571 skinframe->hasalpha = false;
2572
2573 // if no data was provided, then clearly the caller wanted to get a blank skinframe
2574 if (!skindata)
2575 return NULL;
2576
2578 Con_Printf("loading 32bit skin \"%s\"\n", name);
2579
2581 {
2582 unsigned char *a = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8);
2583 unsigned char *b = a + width * height * 4;
2585 skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_nmap", skinframe->basename), width, height, b, TEXTYPE_BGRA, (textureflags | TEXF_ALPHA) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), -1, NULL);
2586 Mem_Free(a);
2587 }
2588 skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, sRGB ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags, -1, NULL);
2589 if (textureflags & TEXF_ALPHA)
2590 {
2591 for (i = 3;i < width * height * 4;i += 4)
2592 {
2593 if (skindata[i] < 255)
2594 {
2595 skinframe->hasalpha = true;
2596 break;
2597 }
2598 }
2599 if (r_loadfog && skinframe->hasalpha)
2600 {
2601 unsigned char *fogpixels = (unsigned char *)Mem_Alloc(tempmempool, width * height * 4);
2603 for (i = 0;i < width * height * 4;i += 4)
2604 fogpixels[i] = fogpixels[i+1] = fogpixels[i+2] = 255;
2605 skinframe->fog = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_fog", skinframe->basename), width, height, fogpixels, TEXTYPE_BGRA, textureflags, -1, NULL);
2607 }
2608 }
2609
2611 //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]);
2612
2613 return skinframe;
2614}
2615
2616skinframe_t *R_SkinFrame_LoadInternalQuake(const char *name, int textureflags, int loadpantsandshirt, int loadglowtexture, const unsigned char *skindata, int width, int height)
2617{
2618 int i;
2619 int featuresmask;
2620 skinframe_t *skinframe;
2621
2622 if (cls.state == ca_dedicated)
2623 return NULL;
2624
2625 // if already loaded just return it, otherwise make a new skinframe
2626 skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height) : 0, true);
2627 if (skinframe->base)
2628 return skinframe;
2629 //textureflags &= ~TEXF_FORCE_RELOAD;
2630
2631 skinframe->stain = NULL;
2632 skinframe->merged = NULL;
2633 skinframe->base = NULL;
2634 skinframe->pants = NULL;
2635 skinframe->shirt = NULL;
2636 skinframe->nmap = NULL;
2637 skinframe->gloss = NULL;
2638 skinframe->glow = NULL;
2639 skinframe->fog = NULL;
2640 skinframe->reflect = NULL;
2641 skinframe->hasalpha = false;
2642
2643 // if no data was provided, then clearly the caller wanted to get a blank skinframe
2644 if (!skindata)
2645 return NULL;
2646
2648 Con_Printf("loading quake skin \"%s\"\n", name);
2649
2650 // we actually don't upload anything until the first use, because mdl skins frequently go unused, and are almost never used in both modes (colormapped and non-colormapped)
2651 skinframe->qpixels = (unsigned char *)Mem_Alloc(r_main_mempool, width*height); // FIXME LEAK
2652 memcpy(skinframe->qpixels, skindata, width*height);
2653 skinframe->qwidth = width;
2654 skinframe->qheight = height;
2655
2656 featuresmask = 0;
2657 for (i = 0;i < width * height;i++)
2659
2660 skinframe->hasalpha = false;
2661 // fence textures
2662 if (name[0] == '{')
2663 skinframe->hasalpha = true;
2666 skinframe->qgeneratemerged = true;
2667 skinframe->qgeneratebase = skinframe->qhascolormapping;
2669
2671 //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]);
2672
2673 return skinframe;
2674}
2675
2677{
2678 int width;
2679 int height;
2680 unsigned char *skindata;
2681 char vabuf[1024];
2682
2683 if (!skinframe->qpixels)
2684 return;
2685
2686 if (!skinframe->qhascolormapping)
2687 colormapped = false;
2688
2689 if (colormapped)
2690 {
2691 if (!skinframe->qgeneratebase)
2692 return;
2693 }
2694 else
2695 {
2696 if (!skinframe->qgeneratemerged)
2697 return;
2698 }
2699
2700 width = skinframe->qwidth;
2701 height = skinframe->qheight;
2702 skindata = skinframe->qpixels;
2703
2704 if (skinframe->qgeneratenmap)
2705 {
2706 unsigned char *a, *b;
2707 skinframe->qgeneratenmap = false;
2708 a = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8);
2709 b = a + width * height * 4;
2710 // use either a custom palette or the quake palette
2713 skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_nmap", skinframe->basename), width, height, b, TEXTYPE_BGRA, (skinframe->textureflags | TEXF_ALPHA) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), -1, NULL);
2714 Mem_Free(a);
2715 }
2716
2717 if (skinframe->qgenerateglow)
2718 {
2719 skinframe->qgenerateglow = false;
2720 if (skinframe->hasalpha) // fence textures
2722 else
2724 }
2725
2726 if (colormapped)
2727 {
2728 skinframe->qgeneratebase = false;
2732 }
2733 else
2734 {
2735 skinframe->qgeneratemerged = false;
2736 if (skinframe->hasalpha) // fence textures
2738 else
2740 }
2741
2742 if (!skinframe->qgeneratemerged && !skinframe->qgeneratebase)
2743 {
2744 Mem_Free(skinframe->qpixels);
2745 skinframe->qpixels = NULL;
2746 }
2747}
2748
2749skinframe_t *R_SkinFrame_LoadInternal8bit(const char *name, int textureflags, const unsigned char *skindata, int width, int height, const unsigned int *palette, const unsigned int *alphapalette)
2750{
2751 int i;
2752 skinframe_t *skinframe;
2753 char vabuf[1024];
2754
2755 if (cls.state == ca_dedicated)
2756 return NULL;
2757
2758 // if already loaded just return it, otherwise make a new skinframe
2759 skinframe = R_SkinFrame_Find(name, textureflags, width, height, skindata ? CRC_Block(skindata, width*height) : 0, true);
2760 if (skinframe->base)
2761 return skinframe;
2762 textureflags &= ~TEXF_FORCE_RELOAD;
2763
2764 skinframe->stain = NULL;
2765 skinframe->merged = NULL;
2766 skinframe->base = NULL;
2767 skinframe->pants = NULL;
2768 skinframe->shirt = NULL;
2769 skinframe->nmap = NULL;
2770 skinframe->gloss = NULL;
2771 skinframe->glow = NULL;
2772 skinframe->fog = NULL;
2773 skinframe->reflect = NULL;
2774 skinframe->hasalpha = false;
2775
2776 // if no data was provided, then clearly the caller wanted to get a blank skinframe
2777 if (!skindata)
2778 return NULL;
2779
2781 Con_Printf("loading embedded 8bit image \"%s\"\n", name);
2782
2783 skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_PALETTE, textureflags, -1, palette);
2784 if ((textureflags & TEXF_ALPHA) && alphapalette)
2785 {
2786 for (i = 0;i < width * height;i++)
2787 {
2788 if (((unsigned char *)palette)[skindata[i]*4+3] < 255)
2789 {
2790 skinframe->hasalpha = true;
2791 break;
2792 }
2793 }
2794 if (r_loadfog && skinframe->hasalpha)
2795 skinframe->fog = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "%s_fog", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, textureflags, -1, alphapalette);
2796 }
2797
2798 R_SKINFRAME_LOAD_AVERAGE_COLORS(width * height, ((unsigned char *)palette)[skindata[pix]*4 + comp]);
2799 //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]);
2800
2801 return skinframe;
2802}
2803
2805{
2806 skinframe_t *skinframe;
2807
2808 if (cls.state == ca_dedicated)
2809 return NULL;
2810
2811 skinframe = R_SkinFrame_Find("missing", TEXF_FORCENEAREST, 0, 0, 0, true);
2812 skinframe->stain = NULL;
2813 skinframe->merged = NULL;
2814 skinframe->base = NULL;
2815 skinframe->pants = NULL;
2816 skinframe->shirt = NULL;
2817 skinframe->nmap = NULL;
2818 skinframe->gloss = NULL;
2819 skinframe->glow = NULL;
2820 skinframe->fog = NULL;
2821 skinframe->reflect = NULL;
2822 skinframe->hasalpha = false;
2823
2824 skinframe->avgcolor[0] = rand() / RAND_MAX;
2825 skinframe->avgcolor[1] = rand() / RAND_MAX;
2826 skinframe->avgcolor[2] = rand() / RAND_MAX;
2827 skinframe->avgcolor[3] = 1;
2828
2829 return skinframe;
2830}
2831
2833{
2834 if (cls.state == ca_dedicated)
2835 return NULL;
2836
2837 return R_SkinFrame_LoadInternalBGRA("notexture", TEXF_FORCENEAREST, Image_GenerateNoTexture(), 16, 16, 0, 0, 0, false);
2838}
2839
2841{
2842 skinframe_t *skinframe;
2843 if (cls.state == ca_dedicated)
2844 return NULL;
2845 // if already loaded just return it, otherwise make a new skinframe
2846 skinframe = R_SkinFrame_Find(name, textureflags, width, height, 0, true);
2847 if (skinframe->base)
2848 return skinframe;
2849 textureflags &= ~TEXF_FORCE_RELOAD;
2850 skinframe->stain = NULL;
2851 skinframe->merged = NULL;
2852 skinframe->base = NULL;
2853 skinframe->pants = NULL;
2854 skinframe->shirt = NULL;
2855 skinframe->nmap = NULL;
2856 skinframe->gloss = NULL;
2857 skinframe->glow = NULL;
2858 skinframe->fog = NULL;
2859 skinframe->reflect = NULL;
2860 skinframe->hasalpha = (textureflags & TEXF_ALPHA) != 0;
2861 // if no data was provided, then clearly the caller wanted to get a blank skinframe
2862 if (!tex)
2863 return NULL;
2865 Con_Printf("loading 32bit skin \"%s\"\n", name);
2866 skinframe->base = skinframe->merged = tex;
2867 Vector4Set(skinframe->avgcolor, 1, 1, 1, 1); // bogus placeholder
2868 return skinframe;
2869}
2870
2871//static char *suffix[6] = {"ft", "bk", "rt", "lf", "up", "dn"};
2872typedef struct suffixinfo_s
2873{
2874 const char *suffix;
2875 qbool flipx, flipy, flipdiagonal;
2876}
2878static suffixinfo_t suffix[3][6] =
2879{
2880 {
2881 {"px", false, false, false},
2882 {"nx", false, false, false},
2883 {"py", false, false, false},
2884 {"ny", false, false, false},
2885 {"pz", false, false, false},
2886 {"nz", false, false, false}
2887 },
2888 {
2889 {"posx", false, false, false},
2890 {"negx", false, false, false},
2891 {"posy", false, false, false},
2892 {"negy", false, false, false},
2893 {"posz", false, false, false},
2894 {"negz", false, false, false}
2895 },
2896 {
2897 {"rt", true, false, true},
2898 {"lf", false, true, true},
2899 {"ft", true, true, false},
2900 {"bk", false, false, false},
2901 {"up", true, false, true},
2902 {"dn", true, false, true}
2903 }
2904};
2905
2906static int componentorder[4] = {0, 1, 2, 3};
2907
2908static rtexture_t *R_LoadCubemap(const char *basename)
2909{
2910 int i, j, cubemapsize, forcefilter;
2911 unsigned char *cubemappixels, *image_buffer;
2913 char name[256];
2914
2915 // HACK: if the cubemap name starts with a !, the cubemap is nearest-filtered
2917 if (basename && basename[0] == '!')
2918 {
2919 basename++;
2921 }
2922 // must start 0 so the first loadimagepixels has no requested width/height
2923 cubemapsize = 0;
2926 // keep trying different suffix groups (posx, px, rt) until one loads
2927 for (j = 0;j < 3 && !cubemappixels;j++)
2928 {
2929 // load the 6 images in the suffix group
2930 for (i = 0;i < 6;i++)
2931 {
2932 // generate an image name based on the base and and suffix
2933 dpsnprintf(name, sizeof(name), "%s%s", basename, suffix[j][i].suffix);
2934 // load it
2935 if ((image_buffer = loadimagepixelsbgra(name, false, false, false, NULL)))
2936 {
2937 // an image loaded, make sure width and height are equal
2939 {
2940 // if this is the first image to load successfully, allocate the cubemap memory
2941 if (!cubemappixels && image_width >= 1)
2942 {
2944 // note this clears to black, so unavailable sides are black
2946 }
2947 // copy the image with any flipping needed by the suffix (px and posx types don't need flipping)
2948 if (cubemappixels)
2950 }
2951 else
2952 Con_Printf("Cubemap image \"%s\" (%ix%i) is not square, OpenGL requires square cubemaps.\n", name, image_width, image_height);
2953 // free the image
2955 }
2956 }
2957 }
2958 // if a cubemap loaded, upload it
2959 if (cubemappixels)
2960 {
2962 Con_Printf("loading cubemap \"%s\"\n", basename);
2963
2966 }
2967 else
2968 {
2969 Con_DPrintf("failed to load cubemap \"%s\"\n", basename);
2971 {
2972 Con_Printf("(tried tried images ");
2973 for (j = 0;j < 3;j++)
2974 for (i = 0;i < 6;i++)
2975 Con_Printf("%s\"%s%s.tga\"", j + i > 0 ? ", " : "", basename, suffix[j][i].suffix);
2976 Con_Print(" and was unable to find any of them).\n");
2977 }
2978 }
2979 return cubemaptexture;
2980}
2981
2982rtexture_t *R_GetCubemap(const char *basename)
2983{
2984 int i;
2985 for (i = 0;i < r_texture_numcubemaps;i++)
2986 if (r_texture_cubemaps[i] != NULL)
2987 if (!strcasecmp(r_texture_cubemaps[i]->basename, basename))
2989 if (i >= MAX_CUBEMAPS || !r_main_mempool)
2990 return r_texture_whitecube;
2993 dp_strlcpy(r_texture_cubemaps[i]->basename, basename, sizeof(r_texture_cubemaps[i]->basename));
2995 return r_texture_cubemaps[i]->texture;
2996}
2997
3010
3011static void R_Main_ResizeViewCache(void)
3012{
3013 int numentities = r_refdef.scene.numentities;
3016 if (r_refdef.viewcache.maxentities < numentities)
3017 {
3018 r_refdef.viewcache.maxentities = numentities;
3022 }
3023 // bones_was_here: r_refdef.viewcache.world_pvsbits was (re)allocated here, now done in Mod_BSP_FatPVS()
3024 if (r_refdef.viewcache.world_numleafs != numleafs)
3025 {
3030 }
3031 if (r_refdef.viewcache.world_numsurfaces != numsurfaces)
3032 {
3033 r_refdef.viewcache.world_numsurfaces = numsurfaces;
3037 }
3038}
3039
3041static void gl_main_start(void)
3042{
3055
3058
3059 switch(vid.renderpath)
3060 {
3061 case RENDERPATH_GL32:
3062 case RENDERPATH_GLES2:
3063 r_loadnormalmap = true;
3064 r_loadgloss = true;
3065 r_loadfog = false;
3066#ifdef GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT
3068#endif
3069 break;
3070 }
3071
3075
3076 r_numqueries = 0;
3077 r_maxqueries = 0;
3078 memset(r_queries, 0, sizeof(r_queries));
3079
3082
3083 // due to caching of texture_t references, the collision cache must be reset
3085
3086 // set up r_skinframe loading system for textures
3087 memset(&r_skinframe, 0, sizeof(r_skinframe));
3090
3095#ifndef USE_GLES2
3097#endif //USE_GLES2
3101 //r_texture_fogintensity = NULL;
3102 memset(&r_fb, 0, sizeof(r_fb));
3107 memset(&r_svbsp, 0, sizeof (r_svbsp));
3108
3111
3113
3114#ifdef __ANDROID__
3115 // For Steelstorm Android
3116 // FIXME CACHE the program and reload
3117 // FIXME see possible combinations for SS:BR android
3118 Con_DPrintf("Compiling most used shaders for SS:BR android... START\n");
3132 Con_DPrintf("Compiling most used shaders for SS:BR android... END\n");
3133#endif
3134}
3135
3136extern unsigned int r_shadow_occlusion_buf;
3137
3138static void gl_main_shutdown(void)
3139{
3145
3147
3148 switch(vid.renderpath)
3149 {
3150 case RENDERPATH_GL32:
3151 case RENDERPATH_GLES2:
3152#if defined(GL_SAMPLES_PASSED) && !defined(USE_GLES2)
3153 if (r_maxqueries)
3155#endif
3156 break;
3157 }
3159 r_numqueries = 0;
3160 r_maxqueries = 0;
3161 memset(r_queries, 0, sizeof(r_queries));
3162
3165
3166 // clear out the r_skinframe state
3168 memset(&r_skinframe, 0, sizeof(r_skinframe));
3169
3170 if (r_svbsp.nodes)
3172 memset(&r_svbsp, 0, sizeof (r_svbsp));
3185 //r_texture_fogintensity = NULL;
3186 memset(&r_fb, 0, sizeof(r_fb));
3188
3192}
3193
3194static void gl_main_newmap(void)
3195{
3196 // FIXME: move this code to client
3197 char *entities, entname[MAX_QPATH];
3198 if (r_qwskincache)
3202 if (cl.worldmodel)
3203 {
3204 dpsnprintf(entname, sizeof(entname), "%s.ent", cl.worldnamenoextension);
3205 if ((entities = (char *)FS_LoadFile(entname, tempmempool, true, NULL)))
3206 {
3207 CL_ParseEntityLump(entities);
3208 Mem_Free(entities);
3209 return;
3210 }
3211 if (cl.worldmodel->brush.entities)
3212 CL_ParseEntityLump(cl.worldmodel->brush.entities);
3213 }
3215
3218}
3219
3221{
3222 int i;
3223 r_main_mempool = Mem_AllocPool("Renderer", 0, NULL);
3225
3226 Cmd_AddCommand(CF_CLIENT, "r_glsl_restart", R_GLSL_Restart_f, "unloads GLSL shaders, they will then be reloaded as needed");
3227 Cmd_AddCommand(CF_CLIENT, "r_glsl_dumpshader", R_GLSL_DumpShader_f, "dumps the engine internal default.glsl shader into glsl/default.glsl");
3228 // FIXME: the client should set up r_refdef.fog stuff including the fogmasktable
3229 if (gamemode == GAME_NEHAHRA)
3230 {
3239 }
3355
3365
3402 for (i = 0;i < R_BUFFERDATA_COUNT;i++)
3409 Cvar_SetValue(&cvars_all, "r_fullbrights", 0);
3410#ifdef DP_MOBILETOUCH
3411 // GLES devices have terrible depth precision in general, so...
3416#endif
3418}
3419
3420void Render_Init(void)
3421{
3424 GL_Main_Init();
3425 Font_Init();
3426 GL_Draw_Init();
3427 R_Shadow_Init();
3428 R_Sky_Init();
3429 GL_Surf_Init();
3430 Sbar_Init();
3436}
3437
3438static void R_GetCornerOfBox(vec3_t out, const vec3_t mins, const vec3_t maxs, int signbits)
3439{
3440 out[0] = ((signbits & 1) ? mins : maxs)[0];
3441 out[1] = ((signbits & 2) ? mins : maxs)[1];
3442 out[2] = ((signbits & 4) ? mins : maxs)[2];
3443}
3444
3445static qbool _R_CullBox(const vec3_t mins, const vec3_t maxs, int numplanes, const mplane_t *planes, int ignore)
3446{
3447 int i;
3448 const mplane_t *p;
3449 vec3_t corner;
3450 if (r_trippy.integer)
3451 return false;
3452 for (i = 0;i < numplanes;i++)
3453 {
3454 if(i == ignore)
3455 continue;
3456 p = planes + i;
3457 R_GetCornerOfBox(corner, mins, maxs, p->signbits);
3458 if (DotProduct(p->normal, corner) < p->dist)
3459 return true;
3460 }
3461 return false;
3462}
3463
3464qbool R_CullFrustum(const vec3_t mins, const vec3_t maxs)
3465{
3466 // skip nearclip plane, it often culls portals when you are very close, and is almost never useful
3468}
3469
3470qbool R_CullBox(const vec3_t mins, const vec3_t maxs, int numplanes, const mplane_t *planes)
3471{
3472 // nothing to ignore
3473 return _R_CullBox(mins, maxs, numplanes, planes, -1);
3474}
3475
3476//==================================================================================
3477
3478// LadyHavoc: this stores temporary data used within the same frame
3479
3480typedef struct r_framedata_mem_s
3481{
3482 struct r_framedata_mem_s *purge; // older mem block to free on next frame
3483 size_t size; // how much usable space
3484 size_t current; // how much space in use
3485 size_t mark; // last "mark" location, temporary memory can be freed by returning to this
3486 size_t wantedsize; // how much space was allocated
3487 unsigned char *data; // start of real data (16byte aligned)
3488}
3490
3492
3494{
3495 while (r_framedata_mem)
3496 {
3499 r_framedata_mem = next;
3500 }
3501}
3502
3504{
3505 size_t wantedsize;
3506 wantedsize = (size_t)(r_framedatasize.value * 1024*1024);
3507 wantedsize = bound(65536, wantedsize, 1000*1024*1024);
3508 if (!r_framedata_mem || r_framedata_mem->wantedsize != wantedsize || mustgrow)
3509 {
3511 newmem->wantedsize = wantedsize;
3512 newmem->data = (unsigned char *)(((size_t)(newmem+1) + 15) & ~15);
3513 newmem->size = (unsigned char *)newmem + wantedsize - newmem->data;
3514 newmem->current = 0;
3515 newmem->mark = 0;
3516 newmem->purge = r_framedata_mem;
3518 }
3519}
3520
3522{
3523 R_FrameData_Resize(false);
3524 if (!r_framedata_mem)
3525 return;
3526 // if we ran out of space on the last frame, free the old memory now
3527 while (r_framedata_mem->purge)
3528 {
3529 // repeatedly remove the second item in the list, leaving only head
3530 r_framedata_mem_t *next = r_framedata_mem->purge->purge;
3532 r_framedata_mem->purge = next;
3533 }
3534 // reset the current mem pointer
3536 r_framedata_mem->mark = 0;
3537}
3538
3540{
3541 void *data;
3542 float newvalue;
3543
3544 // align to 16 byte boundary - the data pointer is already aligned, so we
3545 // only need to ensure the size of every allocation is also aligned
3546 size = (size + 15) & ~15;
3547
3549 {
3550 // emergency - we ran out of space, allocate more memory
3551 // note: this has no upper-bound, we'll fail to allocate memory eventually and just die
3553 // upper bound based on architecture - if we try to allocate more than this we could overflow, better to loop until we error out on allocation failure
3554 if (sizeof(size_t) >= 8)
3555 newvalue = bound(0.25f, newvalue, (float)(1ll << 42));
3556 else
3557 newvalue = bound(0.25f, newvalue, (float)(1 << 10));
3558 // this might not be a growing it, but we'll allocate another buffer every time
3560 R_FrameData_Resize(true);
3561 }
3562
3565
3566 // count the usage for stats
3569
3570 return (void *)data;
3571}
3572
3573void *R_FrameData_Store(size_t size, void *data)
3574{
3575 void *d = R_FrameData_Alloc(size);
3576 if (d && data)
3577 memcpy(d, data, size);
3578 return d;
3579}
3580
3582{
3583 if (!r_framedata_mem)
3584 return;
3586}
3587
3589{
3590 if (!r_framedata_mem)
3591 return;
3593}
3594
3595//==================================================================================
3596
3597// avoid reusing the same buffer objects on consecutive frames
3598#define R_BUFFERDATA_CYCLE 3
3599
3601{
3602 struct r_bufferdata_buffer_s *purge; // older buffer to free on next frame
3603 size_t size; // how much usable space
3604 size_t current; // how much space in use
3605 r_meshbuffer_t *buffer; // the buffer itself
3606}
3608
3609static int r_bufferdata_cycle = 0; // incremented and wrapped each frame
3611
3614{
3615 int cycle, type;
3616 r_bufferdata_buffer_t **p, *mem;
3617 for (cycle = 0;cycle < R_BUFFERDATA_CYCLE;cycle++)
3618 {
3619 for (type = 0;type < R_BUFFERDATA_COUNT;type++)
3620 {
3621 // free all buffers
3623 while (*p)
3624 {
3625 mem = *p;
3626 *p = (*p)->purge;
3627 if (mem->buffer)
3629 Mem_Free(mem);
3630 }
3631 }
3632 }
3633}
3634
3635// resize buffer as needed (this actually makes a new one, the old one will be recycled next frame)
3637{
3639 size_t size;
3641
3642 // increase the cvar if we have to (but only if we already have a mem)
3643 if (mustgrow && mem)
3644 newvalue *= 2.0f;
3645 newvalue = bound(0.25f, newvalue, 256.0f);
3646 while (newvalue * 1024*1024 < minsize)
3647 newvalue *= 2.0f;
3648
3649 // clamp the cvar to valid range
3650 newvalue = bound(0.25f, newvalue, 256.0f);
3653
3654 // calculate size in bytes
3655 size = (size_t)(newvalue * 1024*1024);
3656 size = bound(131072, size, 256*1024*1024);
3657
3658 // allocate a new buffer if the size is different (purge old one later)
3659 // or if we were told we must grow the buffer
3660 if (!mem || mem->size != size || mustgrow)
3661 {
3662 mem = (r_bufferdata_buffer_t *)Mem_Alloc(r_main_mempool, sizeof(*mem));
3663 mem->size = size;
3664 mem->current = 0;
3666 mem->buffer = R_Mesh_CreateMeshBuffer(NULL, mem->size, "dynamicbuffervertex", false, false, true, false);
3667 else if (type == R_BUFFERDATA_INDEX16)
3668 mem->buffer = R_Mesh_CreateMeshBuffer(NULL, mem->size, "dynamicbufferindex16", true, false, true, true);
3669 else if (type == R_BUFFERDATA_INDEX32)
3670 mem->buffer = R_Mesh_CreateMeshBuffer(NULL, mem->size, "dynamicbufferindex32", true, false, true, false);
3671 else if (type == R_BUFFERDATA_UNIFORM)
3672 mem->buffer = R_Mesh_CreateMeshBuffer(NULL, mem->size, "dynamicbufferuniform", false, true, true, false);
3675 }
3676}
3677
3679{
3680 int type;
3681 r_bufferdata_buffer_t **p, *mem;
3682 // cycle to the next frame's buffers
3684 // if we ran out of space on the last time we used these buffers, free the old memory now
3685 for (type = 0;type < R_BUFFERDATA_COUNT;type++)
3686 {
3688 {
3690 // free all but the head buffer, this is how we recycle obsolete
3691 // buffers after they are no longer in use
3693 while (*p)
3694 {
3695 mem = *p;
3696 *p = (*p)->purge;
3697 if (mem->buffer)
3699 Mem_Free(mem);
3700 }
3701 // reset the current offset
3703 }
3704 }
3705}
3706
3708{
3710 int offset = 0;
3711 int padsize;
3712
3713 *returnbufferoffset = 0;
3714
3715 // align size to a byte boundary appropriate for the buffer type, this
3716 // makes all allocations have aligned start offsets
3719 else
3720 padsize = (datasize + 15) & ~15;
3721
3722 // if we ran out of space in this buffer we must allocate a new one
3725
3726 // if the resize did not give us enough memory, fail
3728 Sys_Error("R_BufferData_Store: failed to create a new buffer of sufficient size\n");
3729
3731 offset = (int)mem->current;
3732 mem->current += padsize;
3733
3734 // upload the data to the buffer at the chosen offset
3735 if (offset == 0)
3736 R_Mesh_UpdateMeshBuffer(mem->buffer, NULL, mem->size, false, 0);
3738
3739 // count the usage for stats
3742
3743 // return the buffer offset
3745
3746 return mem->buffer;
3747}
3748
3749//==================================================================================
3750
3751// LadyHavoc: animcache originally written by Echon, rewritten since then
3752
3759{
3760}
3761
3788
3790{
3791 model_t *model = ent->model;
3792 int numvertices;
3793
3794 // see if this ent is worth caching
3795 if (!model || !model->Draw || !model->AnimateVertices)
3796 return false;
3797 // nothing to cache if it contains no animations and has no skeleton
3798 if (!model->surfmesh.isanimated && !(model->num_bones && ent->skeleton && ent->skeleton->relativetransforms))
3799 return false;
3800 // see if it is already cached for gpuskeletal
3802 return false;
3803 // see if it is already cached as a mesh
3804 if (ent->animcache_vertex3f)
3805 {
3806 // check if we need to add normals or tangents
3807 if (ent->animcache_normal3f)
3808 wantnormals = false;
3809 if (ent->animcache_svector3f)
3810 wanttangents = false;
3811 if (!wantnormals && !wanttangents)
3812 return false;
3813 }
3814
3815 // check which kind of cache we need to generate
3816 if (r_gpuskeletal && model->num_bones > 0 && model->surfmesh.data_skeletalindex4ub)
3817 {
3818 // cache the skeleton so the vertex shader can use it
3822 ent->animcache_skeletaltransform3x4 = (float *)R_FrameData_Alloc(sizeof(float[3][4]) * model->num_bones);
3824 // note: this can fail if the buffer is at the grow limit
3825 ent->animcache_skeletaltransform3x4size = sizeof(float[3][4]) * model->num_bones;
3827 }
3828 else if (ent->animcache_vertex3f)
3829 {
3830 // mesh was already cached but we may need to add normals/tangents
3831 // (this only happens with multiple views, reflections, cameras, etc)
3832 if (wantnormals || wanttangents)
3833 {
3834 numvertices = model->surfmesh.num_vertices;
3835 if (wantnormals)
3836 ent->animcache_normal3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
3837 if (wanttangents)
3838 {
3839 ent->animcache_svector3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
3840 ent->animcache_tvector3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
3841 }
3842 model->AnimateVertices(model, ent->frameblend, ent->skeleton, NULL, wantnormals ? ent->animcache_normal3f : NULL, wanttangents ? ent->animcache_svector3f : NULL, wanttangents ? ent->animcache_tvector3f : NULL);
3846 }
3847 }
3848 else
3849 {
3850 // generate mesh cache
3851 numvertices = model->surfmesh.num_vertices;
3852 ent->animcache_vertex3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
3853 if (wantnormals)
3854 ent->animcache_normal3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
3855 if (wanttangents)
3856 {
3857 ent->animcache_svector3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
3858 ent->animcache_tvector3f = (float *)R_FrameData_Alloc(sizeof(float[3])*numvertices);
3859 }
3861 if (wantnormals || wanttangents)
3862 {
3866 }
3870 }
3871 return true;
3872}
3873
3875{
3876 int i;
3877
3878 // TODO: thread this
3879 // NOTE: R_PrepareRTLights() also caches entities
3880
3881 for (i = 0;i < r_refdef.scene.numentities;i++)
3884}
3885
3886//==================================================================================
3887
3889{
3890 long unsigned int i;
3891 int j;
3893 vec3_t boxmins, boxmaxs;
3895 vec3_t start;
3896 vec3_t end;
3898 static vec3_t positions[] = {
3899 { 0.5f, 0.5f, 0.5f },
3900 { 0.0f, 0.0f, 0.0f },
3901 { 0.0f, 0.0f, 1.0f },
3902 { 0.0f, 1.0f, 0.0f },
3903 { 0.0f, 1.0f, 1.0f },
3904 { 1.0f, 0.0f, 0.0f },
3905 { 1.0f, 0.0f, 1.0f },
3906 { 1.0f, 1.0f, 0.0f },
3907 { 1.0f, 1.0f, 1.0f },
3908 };
3909
3910 // sample count can be set to -1 to skip this logic, for flicker-prone objects
3911 if (numsamples < 0)
3912 return true;
3913
3914 // view origin is not used for culling in portal/reflection/refraction renders or isometric views
3916 return true;
3917
3919 return true;
3920
3921 // expand the eye box a little
3922 eyemins[0] = eye[0] - eyejitter;
3923 eyemaxs[0] = eye[0] + eyejitter;
3924 eyemins[1] = eye[1] - eyejitter;
3925 eyemaxs[1] = eye[1] + eyejitter;
3926 eyemins[2] = eye[2] - eyejitter;
3927 eyemaxs[2] = eye[2] + eyejitter;
3928 // expand the box a little
3929 boxmins[0] = (entboxenlarge + 1) * entboxmins[0] - entboxenlarge * entboxmaxs[0] - entboxexpand;
3930 boxmaxs[0] = (entboxenlarge + 1) * entboxmaxs[0] - entboxenlarge * entboxmins[0] + entboxexpand;
3931 boxmins[1] = (entboxenlarge + 1) * entboxmins[1] - entboxenlarge * entboxmaxs[1] - entboxexpand;
3932 boxmaxs[1] = (entboxenlarge + 1) * entboxmaxs[1] - entboxenlarge * entboxmins[1] + entboxexpand;
3933 boxmins[2] = (entboxenlarge + 1) * entboxmins[2] - entboxenlarge * entboxmaxs[2] - entboxexpand;
3934 boxmaxs[2] = (entboxenlarge + 1) * entboxmaxs[2] - entboxenlarge * entboxmins[2] + entboxexpand;
3935 // make an even larger box for the acceptable area
3936 padmins[0] = boxmins[0] - pad;
3937 padmaxs[0] = boxmaxs[0] + pad;
3938 padmins[1] = boxmins[1] - pad;
3939 padmaxs[1] = boxmaxs[1] + pad;
3940 padmins[2] = boxmins[2] - pad;
3941 padmaxs[2] = boxmaxs[2] + pad;
3942
3943 // return true if eye overlaps enlarged box
3944 if (BoxesOverlap(boxmins, boxmaxs, eyemins, eyemaxs))
3945 return true;
3946
3947 VectorCopy(eye, start);
3948 // try specific positions in the box first - note that these can be cached
3950 {
3951 for (i = 0; i < sizeof(positions) / sizeof(positions[0]); i++)
3952 {
3953 trace_t trace;
3954 end[0] = boxmins[0] + (boxmaxs[0] - boxmins[0]) * positions[i][0];
3955 end[1] = boxmins[1] + (boxmaxs[1] - boxmins[1]) * positions[i][1];
3956 end[2] = boxmins[2] + (boxmaxs[2] - boxmins[2]) * positions[i][2];
3957 //trace_t trace = CL_TraceLine(start, end, MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID, SUPERCONTENTS_SKY, MATERIALFLAGMASK_TRANSLUCENT, 0.0f, true, false, NULL, true, true);
3959 // not picky - if the trace ended anywhere in the box we're good
3960 if (BoxesOverlap(trace.endpos, trace.endpos, padmins, padmaxs))
3961 return true;
3962 }
3963 }
3964 else
3965 {
3966 // try center
3967 VectorMAM(0.5f, boxmins, 0.5f, boxmaxs, end);
3968 if (model->brush.TraceLineOfSight(model, start, end, padmins, padmaxs))
3969 return true;
3970 }
3971
3972 // try various random positions
3973 for (j = 0; j < numsamples; j++)
3974 {
3975 VectorSet(start, lhrandom(eyemins[0], eyemaxs[0]), lhrandom(eyemins[1], eyemaxs[1]), lhrandom(eyemins[2], eyemaxs[2]));
3976 VectorSet(end, lhrandom(boxmins[0], boxmaxs[0]), lhrandom(boxmins[1], boxmaxs[1]), lhrandom(boxmins[2], boxmaxs[2]));
3978 {
3979 trace_t trace = CL_TraceLine(start, end, MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID, SUPERCONTENTS_SKY, MATERIALFLAGMASK_TRANSLUCENT, 0.0f, true, false, NULL, true, true);
3980 // not picky - if the trace ended anywhere in the box we're good
3981 if (BoxesOverlap(trace.endpos, trace.endpos, padmins, padmaxs))
3982 return true;
3983 }
3984 else if (model->brush.TraceLineOfSight(model, start, end, padmins, padmaxs))
3985 return true;
3986 }
3987
3988 return false;
3989}
3990
3991
3993{
3994 int i;
3995 int renderimask;
3996 int samples;
3997 entity_render_t *ent;
3998
4003 else
4011 {
4012 // worldmodel can check visibility
4013 for (i = 0;i < r_refdef.scene.numentities;i++)
4014 {
4015 ent = r_refdef.scene.entities[i];
4017 {
4019 continue;
4020 }
4021 if (!(ent->flags & renderimask))
4022 if (!R_CullFrustum(ent->mins, ent->maxs) || (ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)))
4025 }
4026 }
4027 else
4028 {
4029 // no worldmodel or it can't check visibility
4030 for (i = 0;i < r_refdef.scene.numentities;i++)
4031 {
4032 ent = r_refdef.scene.entities[i];
4033 if (!(ent->flags & renderimask))
4034 if (!R_CullFrustum(ent->mins, ent->maxs) || (ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)))
4036 }
4037 }
4039 {
4040 for (i = 0;i < r_refdef.scene.numentities;i++)
4041 {
4043 continue;
4044 ent = r_refdef.scene.entities[i];
4045 if (!(ent->flags & (RENDER_VIEWMODEL | RENDER_WORLDOBJECT | RENDER_NODEPTHTEST)) && !(ent->model && (ent->model->name[0] == '*')))
4046 {
4052 }
4053 }
4054 }
4055}
4056
4058static int R_DrawBrushModelsSky (void)
4059{
4060 int i, sky;
4061 entity_render_t *ent;
4062
4063 sky = false;
4064 for (i = 0;i < r_refdef.scene.numentities;i++)
4065 {
4067 continue;
4068 ent = r_refdef.scene.entities[i];
4069 if (!ent->model || !ent->model->DrawSky)
4070 continue;
4071 ent->model->DrawSky(ent);
4072 sky = true;
4073 }
4074 return sky;
4075}
4076
4077static void R_DrawNoModel(entity_render_t *ent);
4078static void R_DrawModels(void)
4079{
4080 int i;
4081 entity_render_t *ent;
4082
4083 for (i = 0;i < r_refdef.scene.numentities;i++)
4084 {
4086 continue;
4087 ent = r_refdef.scene.entities[i];
4089
4090 if (ent->model && ent->model->Draw != NULL)
4091 ent->model->Draw(ent);
4092 else
4093 R_DrawNoModel(ent);
4094 }
4095}
4096
4097static void R_DrawModelsDepth(void)
4098{
4099 int i;
4100 entity_render_t *ent;
4101
4102 for (i = 0;i < r_refdef.scene.numentities;i++)
4103 {
4105 continue;
4106 ent = r_refdef.scene.entities[i];
4107 if (ent->model && ent->model->DrawDepth != NULL)
4108 ent->model->DrawDepth(ent);
4109 }
4110}
4111
4112static void R_DrawModelsDebug(void)
4113{
4114 int i;
4115 entity_render_t *ent;
4116
4117 for (i = 0;i < r_refdef.scene.numentities;i++)
4118 {
4120 continue;
4121 ent = r_refdef.scene.entities[i];
4122 if (ent->model && ent->model->DrawDebug != NULL)
4123 ent->model->DrawDebug(ent);
4124 }
4125}
4126
4128{
4129 int i;
4130 entity_render_t *ent;
4131
4132 for (i = 0;i < r_refdef.scene.numentities;i++)
4133 {
4135 continue;
4136 ent = r_refdef.scene.entities[i];
4137 if (ent->model && ent->model->DrawAddWaterPlanes != NULL)
4138 ent->model->DrawAddWaterPlanes(ent);
4139 }
4140}
4141
4142static float irisvecs[7][3] = {{0, 0, 0}, {-1, 0, 0}, {1, 0, 0}, {0, -1, 0}, {0, 1, 0}, {0, 0, -1}, {0, 0, 1}};
4143
4145{
4147 {
4148 vec3_t p;
4153 vec_t brightness = 0.0f;
4154 vec_t goal;
4155 vec_t current;
4156 vec_t d;
4157 int c;
4159 for (c = 0;c < (int)(sizeof(irisvecs)/sizeof(irisvecs[0]));c++)
4160 {
4161 p[0] = point[0] + irisvecs[c][0] * r_hdr_irisadaptation_radius.value;
4162 p[1] = point[1] + irisvecs[c][1] * r_hdr_irisadaptation_radius.value;
4163 p[2] = point[2] + irisvecs[c][2] * r_hdr_irisadaptation_radius.value;
4167 if (d > 0)
4169 }
4170 brightness *= 1.0f / c;
4171 brightness += 0.00001f; // make sure it's never zero
4175 if (current < goal)
4177 else if (current > goal)
4179 if (fabs(r_hdr_irisadaptation_value.value - current) > 0.0001f)
4181 }
4182 else if (r_hdr_irisadaptation_value.value != 1.0f)
4184}
4185
4187extern cvar_t r_lockpvs;
4188
4189static void R_View_SetFrustum(const int *scissor)
4190{
4191 int i;
4192 double fpx = +1, fnx = -1, fpy = +1, fny = -1;
4193 vec3_t forward, left, up, origin, v;
4195 return;
4196 if(scissor)
4197 {
4198 // flipped x coordinates (because x points left here)
4199 fpx = 1.0 - 2.0 * (scissor[0] - r_refdef.view.viewport.x) / (double) (r_refdef.view.viewport.width);
4200 fnx = 1.0 - 2.0 * (scissor[0] + scissor[2] - r_refdef.view.viewport.x) / (double) (r_refdef.view.viewport.width);
4201 // non-flipped y coordinates
4202 fny = -1.0 + 2.0 * (scissor[1] - r_refdef.view.viewport.y) / (double) (r_refdef.view.viewport.height);
4203 fpy = -1.0 + 2.0 * (scissor[1] + scissor[3] - r_refdef.view.viewport.y) / (double) (r_refdef.view.viewport.height);
4204 }
4205
4206 // we can't trust r_refdef.view.forward and friends in reflected scenes
4208
4209#if 0
4210 r_refdef.view.frustum[0].normal[0] = 0 - 1.0 / r_refdef.view.frustum_x;
4211 r_refdef.view.frustum[0].normal[1] = 0 - 0;
4212 r_refdef.view.frustum[0].normal[2] = -1 - 0;
4213 r_refdef.view.frustum[1].normal[0] = 0 + 1.0 / r_refdef.view.frustum_x;
4214 r_refdef.view.frustum[1].normal[1] = 0 + 0;
4215 r_refdef.view.frustum[1].normal[2] = -1 + 0;
4216 r_refdef.view.frustum[2].normal[0] = 0 - 0;
4217 r_refdef.view.frustum[2].normal[1] = 0 - 1.0 / r_refdef.view.frustum_y;
4218 r_refdef.view.frustum[2].normal[2] = -1 - 0;
4219 r_refdef.view.frustum[3].normal[0] = 0 + 0;
4220 r_refdef.view.frustum[3].normal[1] = 0 + 1.0 / r_refdef.view.frustum_y;
4221 r_refdef.view.frustum[3].normal[2] = -1 + 0;
4222#endif
4223
4224#if 0
4226 nudge = 1.0 - 1.0 / (1<<23);
4227 r_refdef.view.frustum[4].normal[0] = 0 - 0;
4228 r_refdef.view.frustum[4].normal[1] = 0 - 0;
4229 r_refdef.view.frustum[4].normal[2] = -1 - -nudge;
4230 r_refdef.view.frustum[4].dist = 0 - -2 * zNear * nudge;
4231 r_refdef.view.frustum[5].normal[0] = 0 + 0;
4232 r_refdef.view.frustum[5].normal[1] = 0 + 0;
4233 r_refdef.view.frustum[5].normal[2] = -1 + -nudge;
4234 r_refdef.view.frustum[5].dist = 0 + -2 * zNear * nudge;
4235#endif
4236
4237
4238
4239#if 0
4240 r_refdef.view.frustum[0].normal[0] = m[3] - m[0];
4241 r_refdef.view.frustum[0].normal[1] = m[7] - m[4];
4242 r_refdef.view.frustum[0].normal[2] = m[11] - m[8];
4243 r_refdef.view.frustum[0].dist = m[15] - m[12];
4244
4245 r_refdef.view.frustum[1].normal[0] = m[3] + m[0];
4246 r_refdef.view.frustum[1].normal[1] = m[7] + m[4];
4247 r_refdef.view.frustum[1].normal[2] = m[11] + m[8];
4248 r_refdef.view.frustum[1].dist = m[15] + m[12];
4249
4250 r_refdef.view.frustum[2].normal[0] = m[3] - m[1];
4251 r_refdef.view.frustum[2].normal[1] = m[7] - m[5];
4252 r_refdef.view.frustum[2].normal[2] = m[11] - m[9];
4253 r_refdef.view.frustum[2].dist = m[15] - m[13];
4254
4255 r_refdef.view.frustum[3].normal[0] = m[3] + m[1];
4256 r_refdef.view.frustum[3].normal[1] = m[7] + m[5];
4257 r_refdef.view.frustum[3].normal[2] = m[11] + m[9];
4258 r_refdef.view.frustum[3].dist = m[15] + m[13];
4259
4260 r_refdef.view.frustum[4].normal[0] = m[3] - m[2];
4261 r_refdef.view.frustum[4].normal[1] = m[7] - m[6];
4262 r_refdef.view.frustum[4].normal[2] = m[11] - m[10];
4263 r_refdef.view.frustum[4].dist = m[15] - m[14];
4264
4265 r_refdef.view.frustum[5].normal[0] = m[3] + m[2];
4266 r_refdef.view.frustum[5].normal[1] = m[7] + m[6];
4267 r_refdef.view.frustum[5].normal[2] = m[11] + m[10];
4268 r_refdef.view.frustum[5].dist = m[15] + m[14];
4269#endif
4270
4272 {
4273 // calculate frustum corners, which are used to calculate deformed frustum planes for shadow caster culling
4274 VectorMAMAM(1024, forward, fnx * 1024.0 * r_refdef.view.frustum_x, left, fny * 1024.0 * r_refdef.view.frustum_y, up, r_refdef.view.frustumcorner[0]);
4275 VectorMAMAM(1024, forward, fpx * 1024.0 * r_refdef.view.frustum_x, left, fny * 1024.0 * r_refdef.view.frustum_y, up, r_refdef.view.frustumcorner[1]);
4276 VectorMAMAM(1024, forward, fnx * 1024.0 * r_refdef.view.frustum_x, left, fpy * 1024.0 * r_refdef.view.frustum_y, up, r_refdef.view.frustumcorner[2]);
4277 VectorMAMAM(1024, forward, fpx * 1024.0 * r_refdef.view.frustum_x, left, fpy * 1024.0 * r_refdef.view.frustum_y, up, r_refdef.view.frustumcorner[3]);
4278
4279 // then the normals from the corners relative to origin
4284
4285 // in a NORMAL view, forward cross left == up
4286 // in a REFLECTED view, forward cross left == down
4287 // so our cross products above need to be adjusted for a left handed coordinate system
4288 CrossProduct(forward, left, v);
4289 if(DotProduct(v, up) < 0)
4290 {
4295 }
4296
4297 // Leaving those out was a mistake, those were in the old code, and they
4298 // fix a reproducable bug in this one: frustum culling got fucked up when viewmatrix was an identity matrix
4299 // I couldn't reproduce it after adding those normalizations. --blub
4304
4305 // make the corners absolute
4310
4311 // one more normal
4313
4319 }
4320 else
4321 {
4322 VectorScale(left, -1.0f, r_refdef.view.frustum[0].normal);
4323 VectorScale(left, 1.0f, r_refdef.view.frustum[1].normal);
4332 }
4334
4336 {
4339 }
4340
4341 for (i = 0;i < r_refdef.view.numfrustumplanes;i++)
4343
4344 // LadyHavoc: note to all quake engine coders, Quake had a special case
4345 // for 90 degrees which assumed a square view (wrong), so I removed it,
4346 // Quake2 has it disabled as well.
4347
4348 // rotate R_VIEWFORWARD right by FOV_X/2 degrees
4349 //RotatePointAroundVector( r_refdef.view.frustum[0].normal, up, forward, -(90 - r_refdef.fov_x / 2));
4350 //r_refdef.view.frustum[0].dist = DotProduct (r_refdef.view.origin, frustum[0].normal);
4351 //PlaneClassify(&frustum[0]);
4352
4353 // rotate R_VIEWFORWARD left by FOV_X/2 degrees
4354 //RotatePointAroundVector( r_refdef.view.frustum[1].normal, up, forward, (90 - r_refdef.fov_x / 2));
4355 //r_refdef.view.frustum[1].dist = DotProduct (r_refdef.view.origin, frustum[1].normal);
4356 //PlaneClassify(&frustum[1]);
4357
4358 // rotate R_VIEWFORWARD up by FOV_X/2 degrees
4359 //RotatePointAroundVector( r_refdef.view.frustum[2].normal, left, forward, -(90 - r_refdef.fov_y / 2));
4360 //r_refdef.view.frustum[2].dist = DotProduct (r_refdef.view.origin, frustum[2].normal);
4361 //PlaneClassify(&frustum[2]);
4362
4363 // rotate R_VIEWFORWARD down by FOV_X/2 degrees
4364 //RotatePointAroundVector( r_refdef.view.frustum[3].normal, left, forward, (90 - r_refdef.fov_y / 2));
4365 //r_refdef.view.frustum[3].dist = DotProduct (r_refdef.view.origin, frustum[3].normal);
4366 //PlaneClassify(&frustum[3]);
4367
4368 // nearclip plane
4369 //VectorCopy(forward, r_refdef.view.frustum[4].normal);
4370 //r_refdef.view.frustum[4].dist = DotProduct (r_refdef.view.origin, frustum[4].normal) + r_nearclip.value;
4371 //PlaneClassify(&frustum[4]);
4372}
4373
4381
4383
4385{
4386 const float *customclipplane = NULL;
4387 float plane[4];
4388 int viewy_adjusted;
4390 {
4391 // LadyHavoc: couldn't figure out how to make this approach work the same in DPSOFTRAST
4395 dist = r_refdef.view.clipplane.dist;
4396 plane[0] = r_refdef.view.clipplane.normal[0];
4397 plane[1] = r_refdef.view.clipplane.normal[1];
4398 plane[2] = r_refdef.view.clipplane.normal[2];
4399 plane[3] = -dist;
4400 customclipplane = plane;
4401 }
4402
4403 // GL is weird because it's bottom to top, r_refdef.view.y is top to bottom.
4404 // Unless the render target is a FBO...
4406
4411 else
4415}
4416
4438
4440{
4441 r_viewport_t viewport;
4442 int viewy_adjusted;
4443
4445
4446 // GL is weird because it's bottom to top, r_refdef.view.y is top to bottom.
4447 // Unless the render target is a FBO...
4449
4452 R_SetViewport(&viewport);
4453 GL_Scissor(viewport.x, viewport.y, viewport.width, viewport.height);
4454 GL_Color(1, 1, 1, 1);
4457 GL_ScissorTest(false);
4458 GL_DepthMask(false);
4459 GL_DepthRange(0, 1);
4460 GL_DepthTest(false);
4464 GL_PolygonOffset(0, 0);
4465 switch(vid.renderpath)
4466 {
4467 case RENDERPATH_GL32:
4468 case RENDERPATH_GLES2:
4470 break;
4471 }
4473
4475}
4476
4481
4506
4507/*
4508================
4509R_RenderView_UpdateViewVectors
4510================
4511*/
4513{
4514 // break apart the view matrix into vectors for various purposes
4515 // it is important that this occurs outside the RenderScene function because that can be called from reflection renders, where the vectors come out wrong
4516 // however the r_refdef.view.origin IS updated in RenderScene intentionally - otherwise the sky renders at the wrong origin, etc
4519 // make an inverted copy of the view matrix for tracking sprites
4521}
4522
4524{
4525 unsigned int i, j, end;
4526 end = (unsigned int)Mem_ExpandableArray_IndexRange(&r_fb.rendertargets); // checked
4527 for (i = 0; i < end; i++)
4528 {
4530 // free resources for rendertargets that have not been used for a while
4531 // (note: this check is run after the frame render, so any targets used
4532 // this frame will not be affected even at low framerates)
4533 if (r && (host.realtime - r->lastusetime > 0.2 || force))
4534 {
4535 if (r->fbo)
4537 for (j = 0; j < sizeof(r->colortexture) / sizeof(r->colortexture[0]); j++)
4538 if (r->colortexture[j])
4539 R_FreeTexture(r->colortexture[j]);
4540 if (r->depthtexture)
4541 R_FreeTexture(r->depthtexture);
4543 }
4544 }
4545}
4546
4547static void R_CalcTexCoordsForView(float x, float y, float w, float h, float tw, float th, float *texcoord2f)
4548{
4549 float iw = 1.0f / tw, ih = 1.0f / th, x1, y1, x2, y2;
4550 x1 = x * iw;
4551 x2 = (x + w) * iw;
4552 y1 = (th - y) * ih;
4553 y2 = (th - y - h) * ih;
4554 texcoord2f[0] = x1;
4555 texcoord2f[2] = x2;
4556 texcoord2f[4] = x2;
4557 texcoord2f[6] = x1;
4558 texcoord2f[1] = y1;
4559 texcoord2f[3] = y1;
4560 texcoord2f[5] = y2;
4561 texcoord2f[7] = y2;
4562}
4563
4565{
4566 unsigned int i, j, end;
4568 char vabuf[256];
4569 // first try to reuse an existing slot if possible
4570 end = (unsigned int)Mem_ExpandableArray_IndexRange(&r_fb.rendertargets); // checked
4571 for (i = 0; i < end; i++)
4572 {
4574 if (r && r->lastusetime != host.realtime && r->texturewidth == texturewidth && r->textureheight == textureheight && r->depthtextype == depthtextype && r->colortextype[0] == colortextype0 && r->colortextype[1] == colortextype1 && r->colortextype[2] == colortextype2 && r->colortextype[3] == colortextype3)
4575 break;
4576 }
4577 if (i == end)
4578 {
4579 // no unused exact match found, so we have to make one in the first unused slot
4581 r->texturewidth = texturewidth;
4582 r->textureheight = textureheight;
4583 r->colortextype[0] = colortextype0;
4584 r->colortextype[1] = colortextype1;
4585 r->colortextype[2] = colortextype2;
4586 r->colortextype[3] = colortextype3;
4587 r->depthtextype = depthtextype;
4588 r->depthisrenderbuffer = depthisrenderbuffer;
4589 for (j = 0; j < 4; j++)
4590 if (r->colortextype[j])
4591 r->colortexture[j] = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "rendertarget%i_%i_type%i", i, j, (int)r->colortextype[j]), r->texturewidth, r->textureheight, NULL, r->colortextype[j], TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
4592 if (r->depthtextype)
4593 {
4594 if (r->depthisrenderbuffer)
4595 r->depthtexture = R_LoadTextureRenderBuffer(r_main_texturepool, va(vabuf, sizeof(vabuf), "renderbuffer%i_depth_type%i", i, (int)r->depthtextype), r->texturewidth, r->textureheight, r->depthtextype);
4596 else
4597 r->depthtexture = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "rendertarget%i_depth_type%i", i, (int)r->depthtextype), r->texturewidth, r->textureheight, NULL, r->depthtextype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL);
4598 }
4599 r->fbo = R_Mesh_CreateFramebufferObject(r->depthtexture, r->colortexture[0], r->colortexture[1], r->colortexture[2], r->colortexture[3]);
4600 }
4602 r_refdef.stats[r_stat_rendertargets_pixels] += r->texturewidth * r->textureheight;
4603 r->lastusetime = host.realtime;
4604 R_CalcTexCoordsForView(0, 0, r->texturewidth, r->textureheight, r->texturewidth, r->textureheight, r->texcoord2f);
4605 return r;
4606}
4607
4609{
4610 int waterwidth, waterheight;
4611
4613 return;
4614
4615 // set waterwidth and waterheight to the water resolution that will be
4616 // used (often less than the screen resolution for faster rendering)
4619
4621 waterwidth = waterheight = 0;
4622
4623 // set up variables that will be used in shader setup
4624 r_fb.water.waterwidth = waterwidth;
4625 r_fb.water.waterheight = waterheight;
4626 r_fb.water.texturewidth = waterwidth;
4627 r_fb.water.textureheight = waterheight;
4628 r_fb.water.camerawidth = waterwidth;
4629 r_fb.water.cameraheight = waterheight;
4630 r_fb.water.screenscale[0] = 0.5f;
4631 r_fb.water.screenscale[1] = 0.5f;
4632 r_fb.water.screencenter[0] = 0.5f;
4633 r_fb.water.screencenter[1] = 0.5f;
4634 r_fb.water.enabled = waterwidth != 0;
4635
4638}
4639
4641{
4642 int planeindex, bestplaneindex, vertexindex;
4643 vec3_t mins, maxs, normal, center, v, n;
4645 mplane_t plane;
4647 texture_t *t = R_GetCurrentTexture(surface->texture);
4648
4649 rsurface.texture = t;
4651 // if the model has no normals, it's probably off-screen and they were not generated, so don't add it anyway
4653 return;
4654 // average the vertex normals, find the surface bounds (after deformvertexes)
4658 VectorCopy(v, mins);
4659 VectorCopy(v, maxs);
4661 {
4665 mins[0] = min(mins[0], v[0]);
4666 mins[1] = min(mins[1], v[1]);
4667 mins[2] = min(mins[2], v[2]);
4668 maxs[0] = max(maxs[0], v[0]);
4669 maxs[1] = max(maxs[1], v[1]);
4670 maxs[2] = max(maxs[2], v[2]);
4671 }
4673 VectorMAM(0.5f, mins, 0.5f, maxs, center);
4674
4675 VectorCopy(normal, plane.normal);
4676 VectorNormalize(plane.normal);
4677 plane.dist = DotProduct(center, plane.normal);
4678 PlaneClassify(&plane);
4679 if (PlaneDiff(r_refdef.view.origin, &plane) < 0)
4680 {
4681 // skip backfaces (except if nocullface is set)
4682// if (!(t->currentmaterialflags & MATERIALFLAG_NOCULLFACE))
4683// return;
4684 VectorNegate(plane.normal, plane.normal);
4685 plane.dist *= -1;
4686 PlaneClassify(&plane);
4687 }
4688
4689
4690 // find a matching plane if there is one
4691 bestplaneindex = -1;
4692 bestplanescore = 1048576.0f;
4693 for (planeindex = 0, p = r_fb.water.waterplanes;planeindex < r_fb.water.numwaterplanes;planeindex++, p++)
4694 {
4695 if(p->camera_entity == t->camera_entity)
4696 {
4697 planescore = 1.0f - DotProduct(plane.normal, p->plane.normal) + fabs(plane.dist - p->plane.dist) * 0.001f;
4699 {
4700 bestplaneindex = planeindex;
4702 }
4703 }
4704 }
4705 planeindex = bestplaneindex;
4706
4707 // if this surface does not fit any known plane rendered this frame, add one
4709 {
4711 {
4712 // store the new plane
4713 planeindex = r_fb.water.numwaterplanes++;
4714 p = r_fb.water.waterplanes + planeindex;
4715 p->plane = plane;
4716 // clear materialflags and pvs
4717 p->materialflags = 0;
4718 p->pvsvalid = false;
4720 VectorCopy(mins, p->mins);
4721 VectorCopy(maxs, p->maxs);
4722 }
4723 else
4724 {
4725 // We're totally screwed.
4726 return;
4727 }
4728 }
4729 else
4730 {
4731 // merge mins/maxs when we're adding this surface to the plane
4732 p = r_fb.water.waterplanes + planeindex;
4733 p->mins[0] = min(p->mins[0], mins[0]);
4734 p->mins[1] = min(p->mins[1], mins[1]);
4735 p->mins[2] = min(p->mins[2], mins[2]);
4736 p->maxs[0] = max(p->maxs[0], maxs[0]);
4737 p->maxs[1] = max(p->maxs[1], maxs[1]);
4738 p->maxs[2] = max(p->maxs[2], maxs[2]);
4739 }
4740 // merge this surface's materialflags into the waterplane
4743 {
4744 // merge this surface's PVS into the waterplane
4747 {
4749 p->pvsvalid = true;
4750 }
4751 }
4752}
4753
4754extern cvar_t r_drawparticles;
4755extern cvar_t r_drawdecals;
4756
4757static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, int viewx, int viewy, int viewwidth, int viewheight)
4758{
4759 int myscissor[4];
4762 int planeindex, qualityreduction = 0, old_r_dynamic = 0, old_r_shadows = 0, old_r_worldrtlight = 0, old_r_dlight = 0, old_r_particles = 0, old_r_decals = 0;
4766
4768
4769 // lowquality hack, temporarily shut down some cvars and restore afterwards
4770 qualityreduction = r_water_lowquality.integer;
4771 if (qualityreduction > 0)
4772 {
4773 if (qualityreduction >= 1)
4774 {
4781 }
4782 if (qualityreduction >= 2)
4783 {
4790 }
4791 }
4792
4793 for (planeindex = 0, p = r_fb.water.waterplanes; planeindex < r_fb.water.numwaterplanes; planeindex++, p++)
4794 {
4795 p->rt_reflection = NULL;
4796 p->rt_refraction = NULL;
4797 p->rt_camera = NULL;
4798 }
4799
4800 // render views
4802 r_refdef.view.showdebug = false;
4805 r_refdef.view.useclipplane = true;
4807 r_fb.water.renderingscene = true;
4808 for (planeindex = 0, p = r_fb.water.waterplanes;planeindex < r_fb.water.numwaterplanes;planeindex++, p++)
4809 {
4811 continue;
4812
4814 {
4816 if (rt->colortexture[0] == NULL || rt->depthtexture == NULL)
4817 goto error;
4822 {
4823 R_SetupView(true, rt->fbo, rt->depthtexture, rt->colortexture[0], 0, 0, r_fb.water.waterwidth, r_fb.water.waterheight);
4824 if (R_ScissorForBBox(p->mins, p->maxs, myscissor))
4825 {
4826 p->rt_reflection = NULL;
4827 p->rt_refraction = NULL;
4828 p->rt_camera = NULL;
4829 continue;
4830 }
4831 }
4832
4834 // reflected view origin may be in solid, so don't cull with it
4836 // reverse the cullface settings for this render
4839 // combined pvs (based on what can be seen from each surface center)
4841 {
4842 r_refdef.view.usecustompvs = true;
4843 if (p->pvsvalid)
4845 else
4847 }
4848
4850 R_ResetViewRendering3D(rt->fbo, rt->depthtexture, rt->colortexture[0], 0, 0, rt->texturewidth, rt->textureheight);
4851 GL_ScissorTest(false);
4853 GL_ScissorTest(true);
4858 R_RenderScene(rt->fbo, rt->depthtexture, rt->colortexture[0], 0, 0, rt->texturewidth, rt->textureheight);
4859
4860 r_fb.water.hideplayer = false;
4861 p->rt_reflection = rt;
4862 }
4863
4864 // render the normal view scene and copy into texture
4865 // (except that a clipping plane should be used to hide everything on one side of the water, and the viewer's weapon model should be omitted)
4867 {
4869 if (rt->colortexture[0] == NULL || rt->depthtexture == NULL)
4870 goto error;
4873 {
4874 R_SetupView(true, rt->fbo, rt->depthtexture, rt->colortexture[0], 0, 0, r_fb.water.waterwidth, r_fb.water.waterheight);
4875 if (R_ScissorForBBox(p->mins, p->maxs, myscissor))
4876 {
4877 p->rt_reflection = NULL;
4878 p->rt_refraction = NULL;
4879 p->rt_camera = NULL;
4880 continue;
4881 }
4882 }
4883
4884 // combined pvs (based on what can be seen from each surface center)
4886 {
4887 r_refdef.view.usecustompvs = true;
4888 if (p->pvsvalid)
4890 else
4892 }
4893
4895
4899
4901 {
4902 // we need to perform a matrix transform to render the view... so let's get the transformation matrix
4903 r_fb.water.hideplayer = false; // we don't want to hide the player model from these ones
4907 {
4908 r_refdef.view.usecustompvs = true;
4910 }
4911 }
4912
4914
4915 R_ResetViewRendering3D(rt->fbo, rt->depthtexture, rt->colortexture[0], 0, 0, rt->texturewidth, rt->textureheight);
4916 GL_ScissorTest(false);
4918 GL_ScissorTest(true);
4923 R_RenderScene(rt->fbo, rt->depthtexture, rt->colortexture[0], 0, 0, rt->texturewidth, rt->textureheight);
4924
4925 r_fb.water.hideplayer = false;
4926 p->rt_refraction = rt;
4927 }
4928 else if (p->materialflags & MATERIALFLAG_CAMERA)
4929 {
4931 if (rt->colortexture[0] == NULL || rt->depthtexture == NULL)
4932 goto error;
4934
4938
4941 r_refdef.view.frustum_x = 1; // tan(45 * M_PI / 180.0);
4942 r_refdef.view.frustum_y = 1; // tan(45 * M_PI / 180.0);
4943 r_refdef.view.ortho_x = 90; // abused as angle by VM_CL_R_SetView
4944 r_refdef.view.ortho_y = 90; // abused as angle by VM_CL_R_SetView
4945
4946 if(p->camera_entity)
4947 {
4948 // we need to perform a matrix transform to render the view... so let's get the transformation matrix
4950 }
4951
4952 // note: all of the view is used for displaying... so
4953 // there is no use in scissoring
4954
4955 // reverse the cullface settings for this render
4958 // also reverse the view matrix
4959 Matrix4x4_ConcatScale3(&r_refdef.view.matrix, 1, 1, -1); // this serves to invert texcoords in the result, as the copied texture is mapped the wrong way round
4962 {
4963 r_refdef.view.usecustompvs = true;
4965 }
4966
4967 // camera needs no clipplane
4968 r_refdef.view.useclipplane = false;
4969 // TODO: is the camera origin always valid? if so we don't need to clear this
4971
4973
4974 r_fb.water.hideplayer = false;
4975
4976 R_ResetViewRendering3D(rt->fbo, rt->depthtexture, rt->colortexture[0], 0, 0, rt->texturewidth, rt->textureheight);
4977 GL_ScissorTest(false);
4979 GL_ScissorTest(true);
4982 R_RenderScene(rt->fbo, rt->depthtexture, rt->colortexture[0], 0, 0, rt->texturewidth, rt->textureheight);
4983
4984 r_fb.water.hideplayer = false;
4985 p->rt_camera = rt;
4986 }
4987
4988 }
4989 r_fb.water.renderingscene = false;
4991 R_ResetViewRendering3D(fbo, depthtexture, colortexture, viewx, viewy, viewwidth, viewheight);
4994 goto finish;
4995error:
4997 r_fb.water.renderingscene = false;
4999 Con_Printf("R_Water_ProcessPlanes: Error: texture creation failed! Turned off r_water.\n");
5000finish:
5001 // lowquality hack, restore cvars
5002 if (qualityreduction > 0)
5003 {
5004 if (qualityreduction >= 1)
5005 {
5009 }
5010 if (qualityreduction >= 2)
5011 {
5015 }
5016 }
5017}
5018
5019static void R_Bloom_StartFrame(void)
5020{
5021 int screentexturewidth, screentextureheight;
5023 double scale;
5024
5025 // clear the pointers to rendertargets from last frame as they're stale
5027 r_fb.rt_bloom = NULL;
5028
5029 switch (vid.renderpath)
5030 {
5031 case RENDERPATH_GL32:
5033 if (r_viewfbo.integer == 2) textype = TEXTYPE_COLORBUFFER16F;
5034 if (r_viewfbo.integer == 3) textype = TEXTYPE_COLORBUFFER32F;
5035 break;
5036 case RENDERPATH_GLES2:
5037 r_fb.usedepthtextures = false;
5038 break;
5039 }
5040
5042 {
5043 double actualframetime;
5044 double targetframetime;
5045 double adjust;
5051 {
5052 if (adjust > 0)
5054 else
5056 }
5059 }
5060 else
5061 viewscalefpsadjusted = 1.0f;
5062
5064 if (vid.mode.samples)
5065 scale *= sqrt(vid.mode.samples); // supersampling
5066 scale = bound(0.03125f, scale, 4.0f);
5067 screentexturewidth = (int)ceil(r_refdef.view.width * scale);
5068 screentextureheight = (int)ceil(r_refdef.view.height * scale);
5069 screentexturewidth = bound(1, screentexturewidth, (int)vid.maxtexturesize_2d);
5070 screentextureheight = bound(1, screentextureheight, (int)vid.maxtexturesize_2d);
5071
5072 // set bloomwidth and bloomheight to the bloom resolution that will be
5073 // used (often less than the screen resolution for faster rendering)
5074 r_fb.bloomheight = bound(1, r_bloom_resolution.value * 0.75f, screentextureheight);
5075 r_fb.bloomwidth = r_fb.bloomheight * screentexturewidth / screentextureheight;
5076 r_fb.bloomwidth = bound(1, r_fb.bloomwidth, screentexturewidth);
5079
5081 {
5085 }
5086 if (!r_bloom.integer)
5088
5089 // allocate motionblur ghost texture if needed - this is the only persistent texture and is only useful on the main view
5090 if (r_refdef.view.ismain && (r_fb.screentexturewidth != screentexturewidth || r_fb.screentextureheight != screentextureheight || r_fb.textype != textype))
5091 {
5092 if (r_fb.ghosttexture)
5095
5096 r_fb.screentexturewidth = screentexturewidth;
5097 r_fb.screentextureheight = screentextureheight;
5098 r_fb.textype = textype;
5099
5101 {
5102 if (r_motionblur.value > 0 || r_damageblur.value > 0)
5104 r_fb.ghosttexture_valid = false;
5105 }
5106 }
5107
5108 r_fb.rt_screen = R_RenderTarget_Get(screentexturewidth, screentextureheight, TEXTYPE_DEPTHBUFFER24STENCIL8, true, textype, TEXTYPE_UNUSED, TEXTYPE_UNUSED, TEXTYPE_UNUSED);
5109
5110 r_refdef.view.clear = true;
5111}
5112
5113static void R_Bloom_MakeTexture(void)
5114{
5115 int x, range, dir;
5116 float xoffset, yoffset, r, brighten;
5117 float colorscale = r_bloom_colorscale.value;
5119 r_rendertarget_t *prev, *cur;
5120 textype_t textype = r_fb.rt_screen->colortextype[0];
5121
5123
5125
5126 // scale down screen texture to the bloom texture size
5128 prev = r_fb.rt_screen;
5130 R_Mesh_SetRenderTargets(cur->fbo, NULL, cur->colortexture[0], NULL, NULL, NULL);
5133 GL_DepthTest(false);
5135 GL_Color(colorscale, colorscale, colorscale, 1);
5137 // TODO: do boxfilter scale-down in shader?
5138 R_SetupShader_Generic(prev->colortexture[0], false, true, true);
5141 // we now have a properly scaled bloom image
5142
5143 // multiply bloom image by itself as many times as desired to darken it
5144 // TODO: if people actually use this it could be done more quickly in the previous shader pass
5145 for (x = 1;x < min(r_bloom_colorexponent.value, 32);)
5146 {
5147 prev = cur;
5149 R_Mesh_SetRenderTargets(cur->fbo, NULL, cur->colortexture[0], NULL, NULL, NULL);
5150 x *= 2;
5151 r = bound(0, r_bloom_colorexponent.value / x, 1); // always 0.5 to 1
5152 if(x <= 2)
5154 GL_BlendFunc(GL_SRC_COLOR, GL_ZERO); // square it
5155 GL_Color(1,1,1,1); // no fix factor supported here
5157 R_SetupShader_Generic(prev->colortexture[0], false, true, false);
5160 }
5162
5166 if(range >= 1)
5167 brighten *= (3 * range) / (2 * range - 1); // compensate for the "dot particle"
5168
5169 for (dir = 0;dir < 2;dir++)
5170 {
5171 prev = cur;
5173 R_Mesh_SetRenderTargets(cur->fbo, NULL, cur->colortexture[0], NULL, NULL, NULL);
5174 // blend on at multiple vertical offsets to achieve a vertical blur
5175 // TODO: do offset blends using GLSL
5176 // TODO instead of changing the texcoords, change the target positions to prevent artifacts at edges
5180 R_SetupShader_Generic(prev->colortexture[0], false, true, false);
5182 for (x = -range;x <= range;x++)
5183 {
5184 if (!dir){xoffset = 0;yoffset = x;}
5185 else {xoffset = x;yoffset = 0;}
5186 xoffset /= (float)prev->texturewidth;
5187 yoffset /= (float)prev->textureheight;
5188 // compute a texcoord array with the specified x and y offset
5197 // this r value looks like a 'dot' particle, fading sharply to
5198 // black at the edges
5199 // (probably not realistic but looks good enough)
5200 //r = ((range*range+1)/((float)(x*x+1)))/(range*2+1);
5201 //r = brighten/(range*2+1);
5202 r = brighten / (range * 2 + 1);
5203 if(range >= 1)
5204 r *= (1 - x*x/(float)((range+1)*(range+1)));
5205 if (r <= 0)
5206 continue;
5208 GL_Color(r, r, r, 1);
5217 }
5218 }
5219
5220 // now we have the bloom image, so keep track of it
5221 r_fb.rt_bloom = cur;
5222}
5223
5225{
5226 // Scaling requested?
5227 if (viewwidth != width || viewheight != height)
5228 return false;
5229 // Higher bit depth or explicit FBO requested?
5230 if (r_viewfbo.integer)
5231 return false;
5232 // Non-trivial postprocessing shader permutation?
5233 if (r_fb.bloomwidth
5234 || r_refdef.viewblend[3] > 0
5238 return false;
5239 // Other reasons for a non-trivial default postprocessing shader?
5240 // (See R_CompileShader_CheckStaticParms but only those relevant for MODE_POSTPROCESS in shader_glsl.h)
5241 // Skip: if (r_glsl_saturation_redcompensate.integer) (already covered by saturation above).
5242 // Skip: if (r_glsl_postprocess.integer) (already covered by r_glsl_postprocess above).
5243 // Skip: if (r_glsl_postprocess_uservec1_enable.integer) (already covered by r_glsl_postprocessing above).
5244 if (r_fxaa.integer)
5245 return false;
5246 if (r_colorfringe.value)
5247 return false;
5248 return true;
5249}
5250
5252{
5254
5256 {
5257 // declare variables
5259 static float blur_average;
5260 static vec3_t blur_oldangles; // used to see how quickly the mouse is moving
5261
5262 // set a goal for the factoring
5269
5270 // from the goal, pick an averaged value between goal and last value
5273
5274 // enforce minimum amount of blur
5276
5277 //Con_Printf("motionblur: direct factor: %f, averaged factor: %f, velocity: %f, mouse accel: %f \n", blur_factor, blur_average, blur_velocity, blur_mouseaccel);
5278
5279 // calculate values into a standard alpha
5280 cl.motionbluralpha = 1 - exp(-
5281 (
5283 +
5285 )
5286 /
5287 max(0.0001, cl.time - cl.oldtime) // fps independent
5288 );
5289
5290 // randomization for the blur value to combat persistent ghosting
5293
5294 // apply the blur on top of the current view
5297 {
5299 GL_Color(1, 1, 1, cl.motionbluralpha);
5302 R_SetupShader_Generic(r_fb.ghosttexture, false, true, true);
5305 }
5306
5307 // updates old view angles for next pass
5309
5310 // copy view into the ghost texture
5313 r_fb.ghosttexture_valid = true;
5314 }
5315}
5316
5317static void R_BlendView(rtexture_t *viewcolortexture, int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, int x, int y, int width, int height)
5318{
5319 uint64_t permutation;
5320 float uservecs[4][4];
5323
5325
5326 if (r_fb.bloomwidth)
5327 {
5328 // make the bloom texture
5330 }
5331
5332#if _MSC_VER >= 1400
5333#define sscanf sscanf_s
5334#endif
5335 memset(uservecs, 0, sizeof(uservecs));
5337 sscanf(r_glsl_postprocess_uservec1.string, "%f %f %f %f", &uservecs[0][0], &uservecs[0][1], &uservecs[0][2], &uservecs[0][3]);
5339 sscanf(r_glsl_postprocess_uservec2.string, "%f %f %f %f", &uservecs[1][0], &uservecs[1][1], &uservecs[1][2], &uservecs[1][3]);
5341 sscanf(r_glsl_postprocess_uservec3.string, "%f %f %f %f", &uservecs[2][0], &uservecs[2][1], &uservecs[2][2], &uservecs[2][3]);
5343 sscanf(r_glsl_postprocess_uservec4.string, "%f %f %f %f", &uservecs[3][0], &uservecs[3][1], &uservecs[3][2], &uservecs[3][3]);
5344
5345 // render to the screen fbo
5346 R_ResetViewRendering2D(fbo, depthtexture, colortexture, x, y, width, height);
5347 GL_Color(1, 1, 1, 1);
5349
5352
5354 {
5356 if (rt && rt->colortexture[0])
5357 {
5360 }
5361 }
5362
5364 switch(vid.renderpath)
5365 {
5366 case RENDERPATH_GL32:
5367 case RENDERPATH_GLES2:
5368 permutation =
5388 break;
5389 }
5392}
5393
5395
5396void R_UpdateFog(void)
5397{
5398 // Nehahra fog
5399 if (gamemode == GAME_NEHAHRA)
5400 {
5402 {
5408 r_refdef.fog_alpha = 1;
5409 r_refdef.fog_start = 0;
5411 r_refdef.fog_height = 1<<30;
5412 r_refdef.fog_fadedepth = 128;
5413 }
5414 else if (r_refdef.oldgl_fogenable)
5415 {
5416 r_refdef.oldgl_fogenable = false;
5418 r_refdef.fog_red = 0;
5419 r_refdef.fog_green = 0;
5420 r_refdef.fog_blue = 0;
5421 r_refdef.fog_alpha = 0;
5422 r_refdef.fog_start = 0;
5423 r_refdef.fog_end = 0;
5424 r_refdef.fog_height = 1<<30;
5425 r_refdef.fog_fadedepth = 128;
5426 }
5427 }
5428
5429 // fog parms
5433
5435 {
5436 r_refdef.fogenabled = true;
5437 // this is the point where the fog reaches 0.9986 alpha, which we
5438 // consider a good enough cutoff point for the texture
5439 // (0.9986 * 256 == 255.6)
5440 if (r_fog_exp2.integer)
5442 else
5449 // fog color was already set
5450 // update the fog texture
5455 }
5456 else
5457 r_refdef.fogenabled = false;
5458
5459 // fog color
5461 {
5465
5470
5471 {
5472 vec3_t fogvec;
5474 // color.rgb *= ContrastBoost * SceneBrightness;
5476 r_refdef.fogcolor[0] = bound(0.0f, fogvec[0], 1.0f);
5477 r_refdef.fogcolor[1] = bound(0.0f, fogvec[1], 1.0f);
5478 r_refdef.fogcolor[2] = bound(0.0f, fogvec[2], 1.0f);
5479 }
5480 }
5481}
5482
5484{
5486
5487 r_refdef.scene.ambientintensity = r_ambient.value * (1.0f / 64.0f);
5488
5493
5498
5505 {
5507
5508 // Apply the default lightstyle to the lightmap even on q3bsp
5509 if (cl.worldmodel && cl.worldmodel->type == mod_brushq3) {
5511 }
5512 }
5514 {
5515 r_refdef.scene.rtworld = false;
5517 r_refdef.scene.rtdlight = false;
5520 }
5521
5522 r_gpuskeletal = false;
5523 switch(vid.renderpath)
5524 {
5525 case RENDERPATH_GL32:
5527 case RENDERPATH_GLES2:
5529 {
5531 {
5532 // build GLSL gamma texture
5533#define RAMPWIDTH 256
5534 unsigned short ramp[RAMPWIDTH * 3];
5535 unsigned char rampbgr[RAMPWIDTH][4];
5536 int i;
5537
5539
5541 for(i = 0; i < RAMPWIDTH; ++i)
5542 {
5543 rampbgr[i][0] = (unsigned char) (ramp[i + 2 * RAMPWIDTH] * 255.0 / 65535.0 + 0.5);
5544 rampbgr[i][1] = (unsigned char) (ramp[i + RAMPWIDTH] * 255.0 / 65535.0 + 0.5);
5545 rampbgr[i][2] = (unsigned char) (ramp[i] * 255.0 / 65535.0 + 0.5);
5546 rampbgr[i][3] = 0;
5547 }
5549 {
5550 R_UpdateTexture(r_texture_gammaramps, &rampbgr[0][0], 0, 0, 0, RAMPWIDTH, 1, 1, 0);
5551 }
5552 else
5553 {
5555 }
5556 }
5557 }
5558 else
5559 {
5560 // remove GLSL gamma texture
5561 }
5562 break;
5563 }
5564}
5565
5568/*
5569================
5570R_SelectScene
5571================
5572*/
5574 if( scenetype != r_currentscenetype ) {
5575 // store the old scenetype
5578 // move in the new scene
5580 }
5581}
5582
5583/*
5584================
5585R_GetScenePointer
5586================
5587*/
5589{
5590 // of course, we could also add a qbool that provides a lock state and a ReleaseScenePointer function..
5591 if( scenetype == r_currentscenetype ) {
5592 return &r_refdef.scene;
5593 } else {
5594 return &r_scenes_store[ scenetype ];
5595 }
5596}
5597
5598static int R_SortEntities_Compare(const void *ap, const void *bp)
5599{
5600 const entity_render_t *a = *(const entity_render_t **)ap;
5601 const entity_render_t *b = *(const entity_render_t **)bp;
5602
5603 // 1. compare model
5604 if(a->model < b->model)
5605 return -1;
5606 if(a->model > b->model)
5607 return +1;
5608
5609 // 2. compare skin
5610 // TODO possibly calculate the REAL skinnum here first using
5611 // skinscenes?
5612 if(a->skinnum < b->skinnum)
5613 return -1;
5614 if(a->skinnum > b->skinnum)
5615 return +1;
5616
5617 // everything we compared is equal
5618 return 0;
5619}
5620static void R_SortEntities(void)
5621{
5622 // below or equal 2 ents, sorting never gains anything
5623 if(r_refdef.scene.numentities <= 2)
5624 return;
5625 // sort
5627}
5628
5629/*
5630================
5631R_RenderView
5632================
5633*/
5635extern cvar_t v_isometric;
5636extern void V_MakeViewIsometric(void);
5637void R_RenderView(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, int x, int y, int width, int height)
5638{
5640 int viewfbo = 0;
5645
5646 // finish any 2D rendering that was queued
5647 DrawQ_Finish();
5648
5650 R_TimeReport("start");
5651 r_textureframe++; // used only by R_GetCurrentTexture
5652 rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity
5653
5656
5659 else if (r_sortentities.integer)
5661
5663
5664 /* adjust for stereo display */
5665 if(R_Stereo_Active())
5666 {
5669 }
5670
5672 {
5673 // TODO: FIXME: move this into its own backend function maybe? [2/5/2008 Andreas]
5676 R_TimeReport("depthclear");
5677
5678 r_refdef.view.showdebug = false;
5679
5680 r_fb.water.enabled = false;
5682
5684
5686
5688 return;
5689 }
5690
5691 if (!r_refdef.scene.entities || r_refdef.view.width * r_refdef.view.height == 0 || !r_renderview.integer || cl_videoplaying/* || !r_refdef.scene.worldmodel*/)
5692 {
5694 return;
5695 }
5696
5700
5702
5704 // in sRGB fallback, behave similar to true sRGB: convert this
5705 // value from linear to sRGB
5707
5709
5711
5712 // this will set up r_fb.rt_screen
5714
5715 // apply bloom brightness offset
5716 if(r_fb.rt_bloom)
5718
5720 if (skipblend)
5721 {
5722 // Render to the screen right away.
5723 viewfbo = fbo;
5724 viewdepthtexture = depthtexture;
5725 viewcolortexture = colortexture;
5726 viewx = x;
5727 viewy = y;
5728 viewwidth = width;
5730 }
5731 else if (r_fb.rt_screen)
5732 {
5733 // R_Bloom_StartFrame probably set up an fbo for us to render into, it will be rendered to the window later in R_BlendView
5737 viewx = 0;
5738 viewy = 0;
5741 }
5742
5744
5747 R_TimeReport("viewsetup");
5748
5750
5751 // clear the whole fbo every frame - otherwise the driver will consider
5752 // it to be an inter-frame texture and stall in multi-gpu configurations
5753 if (r_fb.rt_screen)
5754 GL_ScissorTest(false);
5757 R_TimeReport("viewclear");
5758
5759 r_refdef.view.clear = true;
5760
5761 r_refdef.view.showdebug = true;
5762
5765 R_TimeReport("visibility");
5766
5769 R_TimeReport("animcache");
5770
5772 // R_Shadow_UpdateBounceGridTexture called R_TimeReport a few times internally, so we don't need to do that here.
5773
5775 if (r_fb.water.enabled)
5777
5778 // for the actual view render we use scissoring a fair amount, so scissor
5779 // test needs to be on
5780 if (r_fb.rt_screen)
5781 GL_ScissorTest(true);
5785
5786 // postprocess uses textures that are not aligned with the viewport we're rendering, so no scissoring
5787 GL_ScissorTest(false);
5788
5790 if (!skipblend)
5791 R_BlendView(viewcolortexture, fbo, depthtexture, colortexture, x, y, width, height);
5793 R_TimeReport("blendview");
5794
5796
5798
5799 // go back to 2d rendering
5800 DrawQ_Start();
5801}
5802
5827
5828extern cvar_t cl_locs_show;
5829static void R_DrawLocs(void);
5830static void R_DrawEntityBBoxes(prvm_prog_t *prog);
5831static void R_DrawModelDecals(void);
5835{
5836 qbool shadowmapping = false;
5837
5839 R_TimeReport("beginscene");
5840
5842
5843 R_UpdateFog();
5844
5845 // don't let sound skip if going slow
5847 S_ExtraUpdate ();
5848
5850
5852
5854
5856 R_TimeReport("skystartframe");
5857
5859 {
5860 // don't let sound skip if going slow
5862 S_ExtraUpdate ();
5863
5865 {
5868 R_TimeReport("worldsky");
5869 }
5870
5872 R_TimeReport("bmodelsky");
5873
5875 {
5876 // we have to force off the water clipping plane while rendering sky
5878 R_Sky();
5881 R_TimeReport("sky");
5882 }
5883 }
5884
5885 // save the framebuffer info for R_Shadow_RenderMode_Reset during this view render
5893
5897 R_TimeReport("preparelights");
5898
5899 // render all the shadowmaps that will be used for this view
5902 {
5905 R_TimeReport("shadowmaps");
5906 }
5907
5908 // render prepass deferred lighting if r_shadow_deferred is on, this produces light buffers that will be sampled in forward pass
5911
5912 // now we begin the forward pass of the view render
5914 {
5917 R_TimeReport("worlddepth");
5918 }
5919 if (r_depthfirst.integer >= 2)
5920 {
5923 R_TimeReport("modeldepth");
5924 }
5925
5927 {
5930 R_TimeReport("world");
5931 }
5932
5933 // don't let sound skip if going slow
5935 S_ExtraUpdate ();
5936
5937 R_DrawModels();
5939 R_TimeReport("models");
5940
5941 // don't let sound skip if going slow
5943 S_ExtraUpdate ();
5944
5946 {
5949 R_TimeReport("rtlights");
5950 }
5951
5952 // don't let sound skip if going slow
5954 S_ExtraUpdate ();
5955
5957 {
5960 R_TimeReport("modeldecals");
5961
5964 R_TimeReport("particles");
5965
5968 R_TimeReport("explosions");
5969 }
5970
5972 {
5974 {
5975 R_DrawLocs();
5977 R_TimeReport("showlocs");
5978 }
5979
5981 {
5982 R_DrawPortals();
5984 R_TimeReport("portals");
5985 }
5986
5987 if (r_showbboxes_client.value > 0)
5988 {
5991 R_TimeReport("clbboxes");
5992 }
5993 if (r_showbboxes.value > 0)
5994 {
5997 R_TimeReport("svbboxes");
5998 }
5999 }
6000
6002 {
6005 R_TimeReport("drawtrans");
6006 }
6007
6009 {
6012 R_TimeReport("worlddebug");
6015 R_TimeReport("modeldebug");
6016 }
6017
6019 {
6022 R_TimeReport("coronas");
6023 }
6024
6025 // don't let sound skip if going slow
6027 S_ExtraUpdate ();
6028}
6029
6030static const unsigned short bboxelements[36] =
6031{
6032 5, 1, 3, 5, 3, 7,
6033 6, 2, 0, 6, 0, 4,
6034 7, 3, 2, 7, 2, 6,
6035 4, 0, 1, 4, 1, 5,
6036 4, 5, 7, 4, 7, 6,
6037 1, 0, 2, 1, 2, 3,
6038};
6039
6040#define BBOXEDGES 13
6041static const float bboxedges[BBOXEDGES][6] =
6042{
6043 // whole box
6044 { 0, 0, 0, 1, 1, 1 },
6045 // bottom edges
6046 { 0, 0, 0, 0, 1, 0 },
6047 { 0, 0, 0, 1, 0, 0 },
6048 { 0, 1, 0, 1, 1, 0 },
6049 { 1, 0, 0, 1, 1, 0 },
6050 // top edges
6051 { 0, 0, 1, 0, 1, 1 },
6052 { 0, 0, 1, 1, 0, 1 },
6053 { 0, 1, 1, 1, 1, 1 },
6054 { 1, 0, 1, 1, 1, 1 },
6055 // vertical edges
6056 { 0, 0, 0, 0, 0, 1 },
6057 { 1, 0, 0, 1, 0, 1 },
6058 { 0, 1, 0, 0, 1, 1 },
6059 { 1, 1, 0, 1, 1, 1 },
6060};
6061
6062static void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca)
6063{
6064 int numvertices = BBOXEDGES * 8;
6065 float vertex3f[BBOXEDGES * 8 * 3], color4f[BBOXEDGES * 8 * 4];
6066 int numtriangles = BBOXEDGES * 12;
6067 unsigned short elements[BBOXEDGES * 36];
6068 int i, edge;
6069 float *v, *c, f1, f2, edgemins[3], edgemaxs[3];
6070
6071 RSurf_ActiveModelEntity(r_refdef.scene.worldentity, false, false, false);
6072
6074 GL_DepthMask(false);
6075 GL_DepthRange(0, 1);
6077
6078 for (edge = 0; edge < BBOXEDGES; edge++)
6079 {
6080 for (i = 0; i < 3; i++)
6081 {
6082 edgemins[i] = mins[i] + (maxs[i] - mins[i]) * bboxedges[edge][i] - 0.25f;
6083 edgemaxs[i] = mins[i] + (maxs[i] - mins[i]) * bboxedges[edge][3 + i] + 0.25f;
6084 }
6085 vertex3f[edge * 24 + 0] = edgemins[0]; vertex3f[edge * 24 + 1] = edgemins[1]; vertex3f[edge * 24 + 2] = edgemins[2];
6086 vertex3f[edge * 24 + 3] = edgemaxs[0]; vertex3f[edge * 24 + 4] = edgemins[1]; vertex3f[edge * 24 + 5] = edgemins[2];
6087 vertex3f[edge * 24 + 6] = edgemins[0]; vertex3f[edge * 24 + 7] = edgemaxs[1]; vertex3f[edge * 24 + 8] = edgemins[2];
6088 vertex3f[edge * 24 + 9] = edgemaxs[0]; vertex3f[edge * 24 + 10] = edgemaxs[1]; vertex3f[edge * 24 + 11] = edgemins[2];
6089 vertex3f[edge * 24 + 12] = edgemins[0]; vertex3f[edge * 24 + 13] = edgemins[1]; vertex3f[edge * 24 + 14] = edgemaxs[2];
6090 vertex3f[edge * 24 + 15] = edgemaxs[0]; vertex3f[edge * 24 + 16] = edgemins[1]; vertex3f[edge * 24 + 17] = edgemaxs[2];
6091 vertex3f[edge * 24 + 18] = edgemins[0]; vertex3f[edge * 24 + 19] = edgemaxs[1]; vertex3f[edge * 24 + 20] = edgemaxs[2];
6092 vertex3f[edge * 24 + 21] = edgemaxs[0]; vertex3f[edge * 24 + 22] = edgemaxs[1]; vertex3f[edge * 24 + 23] = edgemaxs[2];
6093 for (i = 0; i < 36; i++)
6094 elements[edge * 36 + i] = edge * 8 + bboxelements[i];
6095 }
6096 R_FillColors(color4f, numvertices, cr, cg, cb, ca);
6097 if (r_refdef.fogenabled)
6098 {
6099 for (i = 0, v = vertex3f, c = color4f; i < numvertices; i++, v += 3, c += 4)
6100 {
6101 f1 = RSurf_FogVertex(v);
6102 f2 = 1 - f1;
6103 c[0] = c[0] * f1 + r_refdef.fogcolor[0] * f2;
6104 c[1] = c[1] * f1 + r_refdef.fogcolor[1] * f2;
6105 c[2] = c[2] * f1 + r_refdef.fogcolor[2] * f2;
6106 }
6107 }
6108 R_Mesh_PrepareVertices_Generic_Arrays(numvertices, vertex3f, color4f, NULL);
6110 R_SetupShader_Generic_NoTexture(false, false);
6111 R_Mesh_Draw(0, numvertices, 0, numtriangles, NULL, NULL, 0, elements, NULL, 0);
6112}
6113
6114static void R_DrawEntityBBoxes_Callback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
6115{
6116 // hacky overloading of the parameters
6117 prvm_prog_t *prog = (prvm_prog_t *)rtlight;
6118 int i;
6119 float color[4];
6120 prvm_edict_t *edict;
6121
6123 R_SetupShader_Generic_NoTexture(false, false);
6124
6125 for (i = 0;i < numsurfaces;i++)
6126 {
6127 edict = PRVM_EDICT_NUM(surfacelist[i]);
6128 switch ((int)PRVM_serveredictfloat(edict, solid))
6129 {
6130 case SOLID_NOT: Vector4Set(color, 1, 1, 1, 0.05);break;
6131 case SOLID_TRIGGER: Vector4Set(color, 1, 0, 1, 0.10);break;
6132 case SOLID_BBOX: Vector4Set(color, 0, 1, 0, 0.10);break;
6133 case SOLID_SLIDEBOX: Vector4Set(color, 1, 0, 0, 0.10);break;
6134 case SOLID_BSP: Vector4Set(color, 0, 0, 1, 0.05);break;
6135 case SOLID_CORPSE: Vector4Set(color, 1, 0.5, 0, 0.05);break;
6136 default: Vector4Set(color, 0, 0, 0, 0.50);break;
6137 }
6138 if (prog == CLVM_prog)
6140 else
6141 color[3] *= r_showbboxes.value;
6142 color[3] = bound(0, color[3], 1);
6144 R_DrawBBoxMesh(edict->priv.server->areamins, edict->priv.server->areamaxs, color[0], color[1], color[2], color[3]);
6145 }
6146}
6147
6149{
6150 int i;
6151 prvm_edict_t *edict;
6152 vec3_t center;
6153
6154 if (prog == NULL)
6155 return;
6156
6157 for (i = 0; i < prog->num_edicts; i++)
6158 {
6159 edict = PRVM_EDICT_NUM(i);
6160 if (edict->free)
6161 continue;
6162 // exclude the following for now, as they don't live in world coordinate space and can't be solid:
6163 if (PRVM_gameedictedict(edict, tag_entity) != 0)
6164 continue;
6165 if (prog == SVVM_prog && PRVM_serveredictedict(edict, viewmodelforclient) != 0)
6166 continue;
6167 VectorLerp(edict->priv.server->areamins, 0.5f, edict->priv.server->areamaxs, center);
6169 }
6170}
6171
6172static const int nomodelelement3i[24] =
6173{
6174 5, 2, 0,
6175 5, 1, 2,
6176 5, 0, 3,
6177 5, 3, 1,
6178 0, 2, 4,
6179 2, 1, 4,
6180 3, 0, 4,
6181 1, 3, 4
6182};
6183
6184static const unsigned short nomodelelement3s[24] =
6185{
6186 5, 2, 0,
6187 5, 1, 2,
6188 5, 0, 3,
6189 5, 3, 1,
6190 0, 2, 4,
6191 2, 1, 4,
6192 3, 0, 4,
6193 1, 3, 4
6194};
6195
6196static const float nomodelvertex3f[6*3] =
6197{
6198 -16, 0, 0,
6199 16, 0, 0,
6200 0, -16, 0,
6201 0, 16, 0,
6202 0, 0, -16,
6203 0, 0, 16
6204};
6205
6206static const float nomodelcolor4f[6*4] =
6207{
6208 0.0f, 0.0f, 0.5f, 1.0f,
6209 0.0f, 0.0f, 0.5f, 1.0f,
6210 0.0f, 0.5f, 0.0f, 1.0f,
6211 0.0f, 0.5f, 0.0f, 1.0f,
6212 0.5f, 0.0f, 0.0f, 1.0f,
6213 0.5f, 0.0f, 0.0f, 1.0f
6214};
6215
6216static void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
6217{
6218 int i;
6219 float f1, f2, *c;
6220 float color4f[6*4];
6221
6222 RSurf_ActiveCustomEntity(&ent->matrix, &ent->inversematrix, ent->flags, ent->shadertime, ent->colormod[0], ent->colormod[1], ent->colormod[2], ent->alpha, 6, nomodelvertex3f, NULL, NULL, NULL, NULL, nomodelcolor4f, 8, nomodelelement3i, nomodelelement3s, false, false);
6223
6224 // this is only called once per entity so numsurfaces is always 1, and
6225 // surfacelist is always {0}, so this code does not handle batches
6226
6228 {
6230 GL_DepthMask(false);
6231 }
6232 else if (ent->alpha < 1)
6233 {
6235 GL_DepthMask(false);
6236 }
6237 else
6238 {
6240 GL_DepthMask(true);
6241 }
6242 GL_DepthRange(0, (rsurface.ent_flags & RENDER_VIEWMODEL) ? 0.0625 : 1);
6246 memcpy(color4f, nomodelcolor4f, sizeof(float[6*4]));
6247 for (i = 0, c = color4f;i < 6;i++, c += 4)
6248 {
6249 c[0] *= ent->render_fullbright[0] * r_refdef.view.colorscale;
6250 c[1] *= ent->render_fullbright[1] * r_refdef.view.colorscale;
6251 c[2] *= ent->render_fullbright[2] * r_refdef.view.colorscale;
6252 c[3] *= ent->alpha;
6253 }
6254 if (r_refdef.fogenabled)
6255 {
6256 for (i = 0, c = color4f;i < 6;i++, c += 4)
6257 {
6259 f2 = 1 - f1;
6260 c[0] = (c[0] * f1 + r_refdef.fogcolor[0] * f2);
6261 c[1] = (c[1] * f1 + r_refdef.fogcolor[1] * f2);
6262 c[2] = (c[2] * f1 + r_refdef.fogcolor[2] * f2);
6263 }
6264 }
6265// R_Mesh_ResetTextureState();
6266 R_SetupShader_Generic_NoTexture(false, false);
6269}
6270
6280
6281void R_CalcBeam_Vertex3f (float *vert, const float *org1, const float *org2, float width)
6282{
6284
6286
6287 // calculate 'right' vector for start
6291
6292 // calculate 'right' vector for end
6296
6297 vert[ 0] = org1[0] + width * right1[0];
6298 vert[ 1] = org1[1] + width * right1[1];
6299 vert[ 2] = org1[2] + width * right1[2];
6300 vert[ 3] = org1[0] - width * right1[0];
6301 vert[ 4] = org1[1] - width * right1[1];
6302 vert[ 5] = org1[2] - width * right1[2];
6303 vert[ 6] = org2[0] - width * right2[0];
6304 vert[ 7] = org2[1] - width * right2[1];
6305 vert[ 8] = org2[2] - width * right2[2];
6306 vert[ 9] = org2[0] + width * right2[0];
6307 vert[10] = org2[1] + width * right2[1];
6308 vert[11] = org2[2] + width * right2[2];
6309}
6310
6311void R_CalcSprite_Vertex3f(float *vertex3f, const vec3_t origin, const vec3_t left, const vec3_t up, float scalex1, float scalex2, float scaley1, float scaley2)
6312{
6313 vertex3f[ 0] = origin[0] + left[0] * scalex2 + up[0] * scaley1;
6314 vertex3f[ 1] = origin[1] + left[1] * scalex2 + up[1] * scaley1;
6315 vertex3f[ 2] = origin[2] + left[2] * scalex2 + up[2] * scaley1;
6316 vertex3f[ 3] = origin[0] + left[0] * scalex2 + up[0] * scaley2;
6317 vertex3f[ 4] = origin[1] + left[1] * scalex2 + up[1] * scaley2;
6318 vertex3f[ 5] = origin[2] + left[2] * scalex2 + up[2] * scaley2;
6319 vertex3f[ 6] = origin[0] + left[0] * scalex1 + up[0] * scaley2;
6320 vertex3f[ 7] = origin[1] + left[1] * scalex1 + up[1] * scaley2;
6321 vertex3f[ 8] = origin[2] + left[2] * scalex1 + up[2] * scaley2;
6322 vertex3f[ 9] = origin[0] + left[0] * scalex1 + up[0] * scaley1;
6323 vertex3f[10] = origin[1] + left[1] * scalex1 + up[1] * scaley1;
6324 vertex3f[11] = origin[2] + left[2] * scalex1 + up[2] * scaley1;
6325}
6326
6327static int R_Mesh_AddVertex(rmesh_t *mesh, float x, float y, float z)
6328{
6329 int i;
6330 float *vertex3f;
6331 float v[3];
6332 VectorSet(v, x, y, z);
6333 for (i = 0, vertex3f = mesh->vertex3f;i < mesh->numvertices;i++, vertex3f += 3)
6334 if (VectorDistance2(v, vertex3f) < mesh->epsilon2)
6335 break;
6336 if (i == mesh->numvertices)
6337 {
6338 if (mesh->numvertices < mesh->maxvertices)
6339 {
6340 VectorCopy(v, vertex3f);
6341 mesh->numvertices++;
6342 }
6343 return mesh->numvertices;
6344 }
6345 else
6346 return i;
6347}
6348
6349void R_Mesh_AddPolygon3f(rmesh_t *mesh, int numvertices, float *vertex3f)
6350{
6351 int i;
6352 int *e, element[3];
6353 element[0] = R_Mesh_AddVertex(mesh, vertex3f[0], vertex3f[1], vertex3f[2]);vertex3f += 3;
6354 element[1] = R_Mesh_AddVertex(mesh, vertex3f[0], vertex3f[1], vertex3f[2]);vertex3f += 3;
6355 e = mesh->element3i + mesh->numtriangles * 3;
6356 for (i = 0;i < numvertices - 2;i++, vertex3f += 3)
6357 {
6358 element[2] = R_Mesh_AddVertex(mesh, vertex3f[0], vertex3f[1], vertex3f[2]);
6359 if (mesh->numtriangles < mesh->maxtriangles)
6360 {
6361 *e++ = element[0];
6362 *e++ = element[1];
6363 *e++ = element[2];
6364 mesh->numtriangles++;
6365 }
6366 element[1] = element[2];
6367 }
6368}
6369
6370static void R_Mesh_AddPolygon3d(rmesh_t *mesh, int numvertices, double *vertex3d)
6371{
6372 int i;
6373 int *e, element[3];
6374 element[0] = R_Mesh_AddVertex(mesh, vertex3d[0], vertex3d[1], vertex3d[2]);vertex3d += 3;
6375 element[1] = R_Mesh_AddVertex(mesh, vertex3d[0], vertex3d[1], vertex3d[2]);vertex3d += 3;
6376 e = mesh->element3i + mesh->numtriangles * 3;
6377 for (i = 0;i < numvertices - 2;i++, vertex3d += 3)
6378 {
6379 element[2] = R_Mesh_AddVertex(mesh, vertex3d[0], vertex3d[1], vertex3d[2]);
6380 if (mesh->numtriangles < mesh->maxtriangles)
6381 {
6382 *e++ = element[0];
6383 *e++ = element[1];
6384 *e++ = element[2];
6385 mesh->numtriangles++;
6386 }
6387 element[1] = element[2];
6388 }
6389}
6390
6391#define R_MESH_PLANE_DIST_EPSILON (1.0 / 32.0)
6392void R_Mesh_AddBrushMeshFromPlanes(rmesh_t *mesh, int numplanes, mplane_t *planes)
6393{
6394 int planenum, planenum2;
6395 int w;
6396 int tempnumpoints;
6397 mplane_t *plane, *plane2;
6398 double maxdist;
6399 double temppoints[2][256*3];
6400 // figure out how large a bounding box we need to properly compute this brush
6401 maxdist = 0;
6402 for (w = 0;w < numplanes;w++)
6403 maxdist = max(maxdist, fabs(planes[w].dist));
6404 // now make it large enough to enclose the entire brush, and round it off to a reasonable multiple of 1024
6405 maxdist = floor(maxdist * (4.0 / 1024.0) + 1) * 1024.0;
6406 for (planenum = 0, plane = planes;planenum < numplanes;planenum++, plane++)
6407 {
6408 w = 0;
6409 tempnumpoints = 4;
6410 PolygonD_QuadForPlane(temppoints[w], plane->normal[0], plane->normal[1], plane->normal[2], plane->dist, maxdist);
6412 {
6413 if (planenum2 == planenum)
6414 continue;
6415 PolygonD_Divide(tempnumpoints, temppoints[w], plane2->normal[0], plane2->normal[1], plane2->normal[2], plane2->dist, R_MESH_PLANE_DIST_EPSILON, 0, NULL, NULL, 256, temppoints[!w], &tempnumpoints, NULL);
6416 w = !w;
6417 }
6418 if (tempnumpoints < 3)
6419 continue;
6420 // generate elements forming a triangle fan for this polygon
6422 }
6423}
6424
6425static qbool R_TestQ3WaveFunc(q3wavefunc_t func, const float *parms)
6426{
6427 if(parms[0] == 0 && parms[1] == 0)
6428 return false;
6429 if(func >> Q3WAVEFUNC_USER_SHIFT) // assumes rsurface to be set!
6431 return false;
6432 return true;
6433}
6434
6435static float R_EvaluateQ3WaveFunc(q3wavefunc_t func, const float *parms)
6436{
6437 double index, f;
6438 index = parms[2] + rsurface.shadertime * parms[3];
6439 index -= floor(index);
6440 switch (func & ((1 << Q3WAVEFUNC_USER_SHIFT) - 1))
6441 {
6442 default:
6443 case Q3WAVEFUNC_NONE:
6444 case Q3WAVEFUNC_NOISE:
6445 case Q3WAVEFUNC_COUNT:
6446 f = 0;
6447 break;
6448 case Q3WAVEFUNC_SIN: f = sin(index * M_PI * 2);break;
6449 case Q3WAVEFUNC_SQUARE: f = index < 0.5 ? 1 : -1;break;
6450 case Q3WAVEFUNC_SAWTOOTH: f = index;break;
6451 case Q3WAVEFUNC_INVERSESAWTOOTH: f = 1 - index;break;
6453 index *= 4;
6454 f = index - floor(index);
6455 if (index < 1)
6456 {
6457 // f = f;
6458 }
6459 else if (index < 2)
6460 f = 1 - f;
6461 else if (index < 3)
6462 f = -f;
6463 else
6464 f = -(1 - f);
6465 break;
6466 }
6467 f = parms[0] + parms[1] * f;
6468 if(func >> Q3WAVEFUNC_USER_SHIFT) // assumes rsurface to be set!
6470 return (float) f;
6471}
6472
6473static void R_tcMod_ApplyToMatrix(matrix4x4_t *texmatrix, q3shaderinfo_layer_tcmod_t *tcmod, int currentmaterialflags)
6474{
6475 int w, h, idx;
6476 float shadertime;
6477 float f;
6478 float offsetd[2];
6479 float tcmat[12];
6480 matrix4x4_t matrix, temp;
6481 // if shadertime exceeds about 9 hours (32768 seconds), just wrap it,
6482 // it's better to have one huge fixup every 9 hours than gradual
6483 // degradation over time which looks consistently bad after many hours.
6484 //
6485 // tcmod scroll in particular suffers from this degradation which can't be
6486 // effectively worked around even with floor() tricks because we don't
6487 // know if tcmod scroll is the last tcmod being applied, and for clampmap
6488 // a workaround involving floor() would be incorrect anyway...
6489 shadertime = rsurface.shadertime;
6490 if (shadertime >= 32768.0f)
6491 shadertime -= floor(rsurface.shadertime * (1.0f / 32768.0f)) * 32768.0f;
6492 switch(tcmod->tcmod)
6493 {
6494 case Q3TCMOD_COUNT:
6495 case Q3TCMOD_NONE:
6496 if (currentmaterialflags & MATERIALFLAG_WATERSCROLL)
6497 matrix = r_waterscrollmatrix;
6498 else
6499 matrix = identitymatrix;
6500 break;
6502 // this is used in Q3 to allow the gamecode to control texcoord
6503 // scrolling on the entity, which is not supported in darkplaces yet.
6504 Matrix4x4_CreateTranslate(&matrix, 0, 0, 0);
6505 break;
6506 case Q3TCMOD_ROTATE:
6507 Matrix4x4_CreateTranslate(&matrix, 0.5, 0.5, 0);
6508 Matrix4x4_ConcatRotate(&matrix, tcmod->parms[0] * rsurface.shadertime, 0, 0, 1);
6509 Matrix4x4_ConcatTranslate(&matrix, -0.5, -0.5, 0);
6510 break;
6511 case Q3TCMOD_SCALE:
6512 Matrix4x4_CreateScale3(&matrix, tcmod->parms[0], tcmod->parms[1], 1);
6513 break;
6514 case Q3TCMOD_SCROLL:
6515 // this particular tcmod is a "bug for bug" compatible one with regards to
6516 // Quake3, the wrapping is unnecessary with our shadetime fix but quake3
6517 // specifically did the wrapping and so we must mimic that...
6518 offsetd[0] = tcmod->parms[0] * rsurface.shadertime;
6519 offsetd[1] = tcmod->parms[1] * rsurface.shadertime;
6520 Matrix4x4_CreateTranslate(&matrix, offsetd[0] - floor(offsetd[0]), offsetd[1] - floor(offsetd[1]), 0);
6521 break;
6522 case Q3TCMOD_PAGE: // poor man's animmap (to store animations into a single file, useful for HTTP downloaded textures)
6523 w = (int) tcmod->parms[0];
6524 h = (int) tcmod->parms[1];
6525 f = rsurface.shadertime / (tcmod->parms[2] * w * h);
6526 f = f - floor(f);
6527 idx = (int) floor(f * w * h);
6528 Matrix4x4_CreateTranslate(&matrix, (idx % w) / tcmod->parms[0], (idx / w) / tcmod->parms[1], 0);
6529 break;
6530 case Q3TCMOD_STRETCH:
6531 f = 1.0f / R_EvaluateQ3WaveFunc(tcmod->wavefunc, tcmod->waveparms);
6532 Matrix4x4_CreateFromQuakeEntity(&matrix, 0.5f * (1 - f), 0.5 * (1 - f), 0, 0, 0, 0, f);
6533 break;
6534 case Q3TCMOD_TRANSFORM:
6535 VectorSet(tcmat + 0, tcmod->parms[0], tcmod->parms[1], 0);
6536 VectorSet(tcmat + 3, tcmod->parms[2], tcmod->parms[3], 0);
6537 VectorSet(tcmat + 6, 0 , 0 , 1);
6538 VectorSet(tcmat + 9, tcmod->parms[4], tcmod->parms[5], 0);
6540 break;
6541 case Q3TCMOD_TURBULENT:
6542 // this is handled in the RSurf_PrepareVertices function
6543 matrix = identitymatrix;
6544 break;
6545 }
6546 temp = *texmatrix;
6547 Matrix4x4_Concat(texmatrix, &matrix, &temp);
6548}
6549
6550static void R_LoadQWSkin(r_qwskincache_t *cache, const char *skinname)
6551{
6552 int textureflags = (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_PICMIP;
6553 char name[MAX_QPATH];
6554 skinframe_t *skinframe;
6555 unsigned char pixels[296*194];
6556 dp_strlcpy(cache->name, skinname, sizeof(cache->name));
6557 dpsnprintf(name, sizeof(name), "skins/%s.pcx", cache->name);
6559 Con_Printf("loading %s\n", name);
6560 skinframe = R_SkinFrame_Find(name, textureflags, 0, 0, 0, false);
6561 if (!skinframe || !skinframe->base)
6562 {
6563 unsigned char *f;
6564 fs_offset_t filesize;
6565 skinframe = NULL;
6566 f = FS_LoadFile(name, tempmempool, true, &filesize);
6567 if (f)
6568 {
6569 if (LoadPCX_QWSkin(f, (int)filesize, pixels, 296, 194))
6571 Mem_Free(f);
6572 }
6573 }
6574 cache->skinframe = skinframe;
6575}
6576
6578{
6579 int i, q;
6580 const entity_render_t *ent = rsurface.entity;
6581 model_t *model = ent->model; // when calling this, ent must not be NULL
6583 float specularscale = 0.0f;
6584
6586 return t->currentframe;
6588 t->update_lastrenderentity = (void *)ent;
6589
6590 if(ent->entitynumber >= MAX_EDICTS && ent->entitynumber < 2 * MAX_EDICTS)
6591 t->camera_entity = ent->entitynumber;
6592 else
6593 t->camera_entity = 0;
6594
6595 // switch to an alternate material if this is a q1bsp animated material
6596 {
6597 texture_t *texture = t;
6598 int s = rsurface.ent_skinnum;
6599 if ((unsigned int)s >= (unsigned int)model->numskins)
6600 s = 0;
6601 if (model->skinscenes)
6602 {
6603 if (model->skinscenes[s].framecount > 1)
6604 s = model->skinscenes[s].firstframe + (unsigned int) (rsurface.shadertime * model->skinscenes[s].framerate) % model->skinscenes[s].framecount;
6605 else
6606 s = model->skinscenes[s].firstframe;
6607 }
6608 if (s > 0)
6609 t = t + s * model->num_surfaces;
6610 if (t->animated)
6611 {
6612 // use an alternate animation if the entity's frame is not 0,
6613 // and only if the texture has an alternate animation
6614 if (t->animated == 2) // q2bsp
6615 t = t->anim_frames[0][ent->framegroupblend[0].frame % t->anim_total[0]];
6616 else if (rsurface.ent_alttextures && t->anim_total[1])
6617 t = t->anim_frames[1][(t->anim_total[1] >= 2) ? ((int)(rsurface.shadertime * 5.0f) % t->anim_total[1]) : 0];
6618 else
6619 t = t->anim_frames[0][(t->anim_total[0] >= 2) ? ((int)(rsurface.shadertime * 5.0f) % t->anim_total[0]) : 0];
6620 }
6621 texture->currentframe = t;
6622 }
6623
6624 // update currentskinframe to be a qw skin or animation frame
6625 if (rsurface.ent_qwskin >= 0)
6626 {
6629 {
6631 if (r_qwskincache)
6634 }
6640 }
6641 else if (t->materialshaderpass && t->materialshaderpass->numframes >= 2)
6645
6654
6655 // decide on which type of lighting to use for this surface
6663 {
6664 // some CUSTOMBLEND blendfuncs are too weird, we have to ignore colormod and view colorscale
6666 for (q = 0; q < 3; q++)
6667 {
6674 t->render_lightmap_ambient[q] = 0;
6675 t->render_lightmap_diffuse[q] = 0;
6677 t->render_rtlight_diffuse[q] = 0;
6678 t->render_rtlight_specular[q] = 0;
6679 }
6680 }
6682 {
6683 // fullbright is basically MATERIALFLAG_MODELLIGHT but with ambient locked to 1,1,1 and no shading
6685 for (q = 0; q < 3; q++)
6686 {
6693 t->render_lightmap_ambient[q] = 0;
6694 t->render_lightmap_diffuse[q] = 0;
6696 t->render_rtlight_diffuse[q] = 0;
6697 t->render_rtlight_specular[q] = 0;
6698 }
6699 }
6701 {
6703 for (q = 0; q < 3; q++)
6704 {
6716 }
6717 }
6719 {
6720 // ambient + single direction light (modellight)
6722 for (q = 0; q < 3; q++)
6723 {
6730 t->render_lightmap_ambient[q] = 0;
6731 t->render_lightmap_diffuse[q] = 0;
6735 }
6736 }
6737 else
6738 {
6739 // lightmap - 2x diffuse and specular brightness because bsp files have 0-2 colors as 0-1
6740 for (q = 0; q < 3; q++)
6741 {
6753 }
6754 }
6755
6757 {
6758 // since MATERIALFLAG_VERTEXCOLOR uses the lightmapcolor4f vertex
6759 // attribute, we punt it to the lightmap path and hope for the best,
6760 // but lighting doesn't work.
6761 //
6762 // FIXME: this is fine for effects but CSQC polygons should be subject
6763 // to lighting.
6765 for (q = 0; q < 3; q++)
6766 {
6773 t->render_lightmap_ambient[q] = 0;
6776 t->render_rtlight_diffuse[q] = 0;
6777 t->render_rtlight_specular[q] = 0;
6778 }
6779 }
6780
6781 for (q = 0; q < 3; q++)
6782 {
6785 }
6786
6789 else if (t->currentalpha < 1)
6791 // LadyHavoc: prevent bugs where code checks add or alpha at higher priority than customblend by clearing these flags
6798 if (t->backgroundshaderpass)
6801 {
6804 }
6805 else
6808 {
6809 // promote alphablend to alphatocoverage (a type of alphatest) if antialiasing is on
6811 }
6814
6815 // there is no tcmod
6817 {
6820 }
6822 {
6825 }
6826
6827 if (t->materialshaderpass)
6828 for (i = 0, tcmod = t->materialshaderpass->tcmods;i < Q3MAXTCMODS && tcmod->tcmod;i++, tcmod++)
6830
6832 if (t->currentskinframe->qpixels)
6834 t->basetexture = (!t->colormapping && t->currentskinframe->merged) ? t->currentskinframe->merged : t->currentskinframe->base;
6835 if (!t->basetexture)
6837 t->pantstexture = t->colormapping ? t->currentskinframe->pants : NULL;
6838 t->shirttexture = t->colormapping ? t->currentskinframe->shirt : NULL;
6839 t->nmaptexture = t->currentskinframe->nmap;
6840 if (!t->nmaptexture)
6843 t->glowtexture = t->currentskinframe->glow;
6844 t->fogtexture = t->currentskinframe->fog;
6845 t->reflectmasktexture = t->currentskinframe->reflect;
6846 if (t->backgroundshaderpass)
6847 {
6848 for (i = 0, tcmod = t->backgroundshaderpass->tcmods; i < Q3MAXTCMODS && tcmod->tcmod; i++, tcmod++)
6854 if (!t->backgroundnmaptexture)
6856 // make sure that if glow is going to be used, both textures are not NULL
6857 if (!t->backgroundglowtexture && t->glowtexture)
6859 if (!t->glowtexture && t->backgroundglowtexture)
6861 }
6862 else
6863 {
6868 }
6870 // TODO: store reference values for these in the texture?
6871 if (r_shadow_gloss.integer > 0)
6872 {
6874 {
6876 {
6879 specularscale = r_shadow_glossintensity.value;
6880 }
6881 }
6883 {
6886 specularscale = r_shadow_gloss2intensity.value;
6888 }
6889 }
6890 specularscale *= t->specularscalemod;
6892
6893 // lightmaps mode looks bad with dlights using actual texturing, so turn
6894 // off the colormap and glossmap, but leave the normalmap on as it still
6895 // accurately represents the shading involved
6897 {
6901 if (gl_lightmaps.integer < 2)
6904 t->glowtexture = NULL;
6905 t->fogtexture = NULL;
6908 if (gl_lightmaps.integer < 2)
6912 specularscale = 0;
6914 }
6915
6916 if (specularscale != 1.0f)
6917 {
6918 for (q = 0; q < 3; q++)
6919 {
6920 t->render_modellight_specular[q] *= specularscale;
6921 t->render_lightmap_specular[q] *= specularscale;
6922 t->render_rtlight_specular[q] *= specularscale;
6923 }
6924 }
6925
6926 t->currentblendfunc[0] = GL_ONE;
6927 t->currentblendfunc[1] = GL_ZERO;
6929 {
6931 t->currentblendfunc[1] = GL_ONE;
6932 }
6934 {
6937 }
6939 {
6940 t->currentblendfunc[0] = t->customblendfunc[0];
6941 t->currentblendfunc[1] = t->customblendfunc[1];
6942 }
6943
6944 return t;
6945}
6946
6948
6949void RSurf_ActiveModelEntity(const entity_render_t *ent, qbool wantnormals, qbool wanttangents, qbool prepass)
6950{
6951 model_t *model = ent->model;
6952 //if (rsurface.entity == ent && (!model->surfmesh.isanimated || (!wantnormals && !wanttangents)))
6953 // return;
6955 rsurface.skeleton = ent->skeleton;
6958 rsurface.ent_qwskin = (ent->entitynumber <= cl.maxclients && ent->entitynumber >= 1 && cls.protocol == PROTOCOL_QUAKEWORLD && cl.scores[ent->entitynumber - 1].qw_skin[0] && !strcmp(ent->model->name, "progs/player.mdl")) ? (ent->entitynumber - 1) : -1;
6959 rsurface.ent_flags = ent->flags;
6963 rsurface.matrix = ent->matrix;
6974 memcpy(rsurface.frameblend, ent->frameblend, sizeof(ent->frameblend));
6978 if (ent->model->brush.submodel && !prepass)
6979 {
6982 }
6983 // if the animcache code decided it should use the shader path, skip the deform step
6990 {
6991 if (ent->animcache_vertex3f)
6992 {
7000 rsurface.modelsvector3f = wanttangents ? ent->animcache_svector3f : NULL;
7003 rsurface.modeltvector3f = wanttangents ? ent->animcache_tvector3f : NULL;
7006 rsurface.modelnormal3f = wantnormals ? ent->animcache_normal3f : NULL;
7009 }
7010 else if (wanttangents)
7011 {
7016 rsurface.modelvertex3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
7017 rsurface.modelsvector3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
7018 rsurface.modeltvector3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
7019 rsurface.modelnormal3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
7031 }
7032 else if (wantnormals)
7033 {
7038 rsurface.modelvertex3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
7041 rsurface.modelnormal3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
7053 }
7054 else
7055 {
7060 rsurface.modelvertex3f = (float *)R_FrameData_Alloc(model->surfmesh.num_vertices * sizeof(float[3]));
7075 }
7077 }
7078 else
7079 {
7081 {
7086 }
7087 else
7088 {
7093 }
7107 }
7172}
7173
7174void RSurf_ActiveCustomEntity(const matrix4x4_t *matrix, const matrix4x4_t *inversematrix, int entflags, double shadertime, float r, float g, float b, float a, int numvertices, const float *vertex3f, const float *texcoord2f, const float *normal3f, const float *svector3f, const float *tvector3f, const float *color4f, int numtriangles, const int *element3i, const unsigned short *element3s, qbool wantnormals, qbool wanttangents)
7175{
7177 if (r != 1.0f || g != 1.0f || b != 1.0f || a != 1.0f) {
7178 // HACK to provide a valid entity with modded colors to R_GetCurrentTexture.
7179 // A better approach could be making this copy only once per frame.
7181 int q;
7183 for (q = 0; q < 3; ++q) {
7184 float colormod = q == 0 ? r : q == 1 ? g : b;
7185 custom_entity.render_fullbright[q] *= colormod;
7186 custom_entity.render_modellight_ambient[q] *= colormod;
7187 custom_entity.render_modellight_diffuse[q] *= colormod;
7188 custom_entity.render_lightmap_ambient[q] *= colormod;
7189 custom_entity.render_lightmap_diffuse[q] *= colormod;
7190 custom_entity.render_rtlight_diffuse[q] *= colormod;
7191 }
7192 custom_entity.alpha *= a;
7194 }
7197 rsurface.ent_qwskin = -1;
7199 rsurface.shadertime = r_refdef.scene.time - shadertime;
7200 rsurface.modelnumvertices = numvertices;
7201 rsurface.modelnumtriangles = numtriangles;
7202 rsurface.matrix = *matrix;
7203 rsurface.inversematrix = *inversematrix;
7214 rsurface.frameblend[0].lerp = 1;
7215 rsurface.ent_alttextures = false;
7227 if (wanttangents)
7228 {
7229 rsurface.modelvertex3f = (float *)vertex3f;
7230 rsurface.modelsvector3f = svector3f ? (float *)svector3f : (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
7231 rsurface.modeltvector3f = tvector3f ? (float *)tvector3f : (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
7232 rsurface.modelnormal3f = normal3f ? (float *)normal3f : (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
7233 }
7234 else if (wantnormals)
7235 {
7236 rsurface.modelvertex3f = (float *)vertex3f;
7239 rsurface.modelnormal3f = normal3f ? (float *)normal3f : (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
7240 }
7241 else
7242 {
7243 rsurface.modelvertex3f = (float *)vertex3f;
7247 }
7257 rsurface.modellightmapcolor4f = (float *)color4f;
7260 rsurface.modeltexcoordtexture2f = (float *)texcoord2f;
7272 rsurface.modelelement3i = (int *)element3i;
7275 rsurface.modelelement3s = (unsigned short *)element3s;
7319
7321 {
7322 if ((wantnormals || wanttangents) && !normal3f)
7323 {
7324 rsurface.modelnormal3f = (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
7326 }
7327 if (wanttangents && !svector3f)
7328 {
7329 rsurface.modelsvector3f = (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
7330 rsurface.modeltvector3f = (float *)R_FrameData_Alloc(rsurface.modelnumvertices * sizeof(float[3]));
7332 }
7333 }
7334}
7335
7336float RSurf_FogPoint(const float *v)
7337{
7338 // this code is identical to the USEFOGINSIDE/USEFOGOUTSIDE code in the shader
7342 float fogfrac;
7343 unsigned int fogmasktableindex;
7346 else
7350}
7351
7352float RSurf_FogVertex(const float *v)
7353{
7354 // this code is identical to the USEFOGINSIDE/USEFOGOUTSIDE code in the shader
7358 float fogfrac;
7359 unsigned int fogmasktableindex;
7362 else
7366}
7367
7369{
7370 // upload buffer data for generated vertex data (dynamicvertex case) or index data (copytriangles case) and models that lack it to begin with (e.g. DrawQ_FlushUI)
7371 // note that if rsurface.batchvertex3f_vertexbuffer is NULL, dynamicvertex is forced as we don't account for the proper base vertex here.
7390
7395
7403 R_Mesh_TexCoordPointer(5, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
7406}
7407
7408static void RSurf_RenumberElements(const int *inelement3i, int *outelement3i, int numelements, int adjust)
7409{
7410 int i;
7411 for (i = 0;i < numelements;i++)
7413}
7414
7415static const int quadedges[6][2] = {{0, 1}, {0, 2}, {0, 3}, {1, 2}, {1, 3}, {2, 3}};
7417{
7418 int deformindex;
7419 int firsttriangle;
7420 int numtriangles;
7421 int firstvertex;
7422 int endvertex;
7423 int numvertices;
7427 int surfaceendvertex;
7430 int batchnumvertices;
7431 int batchnumtriangles;
7432 int i, j;
7433 qbool gaps;
7435 float amplitude;
7436 float animpos;
7437 float center[3], forward[3], right[3], up[3], v[3], newforward[3], newright[3], newup[3];
7438 float waveparms[4];
7439 unsigned char *ub;
7440 q3shaderinfo_deform_t *deform;
7441 const msurface_t *surface, *firstsurface;
7442 if (!texturenumsurfaces)
7443 return;
7444 // find vertex range of this surface batch
7445 gaps = false;
7446 firstsurface = texturesurfacelist[0];
7447 firsttriangle = firstsurface->num_firsttriangle;
7448 batchnumvertices = 0;
7449 batchnumtriangles = 0;
7450 firstvertex = endvertex = firstsurface->num_firstvertex;
7451 for (i = 0;i < texturenumsurfaces;i++)
7452 {
7454 if (surface != firstsurface + i)
7455 gaps = true;
7456 surfacefirstvertex = surface->num_firstvertex;
7458 surfacenumvertices = surface->num_vertices;
7459 surfacenumtriangles = surface->num_triangles;
7460 if (firstvertex > surfacefirstvertex)
7461 firstvertex = surfacefirstvertex;
7464 batchnumvertices += surfacenumvertices;
7465 batchnumtriangles += surfacenumtriangles;
7466 }
7467
7469 if (gaps)
7472 r_refdef.stats[r_stat_batch_vertices] += batchnumvertices;
7473 r_refdef.stats[r_stat_batch_triangles] += batchnumtriangles;
7474
7475 // we now know the vertex range used, and if there are any gaps in it
7476 rsurface.batchfirstvertex = firstvertex;
7477 rsurface.batchnumvertices = endvertex - firstvertex;
7479 rsurface.batchnumtriangles = batchnumtriangles;
7480
7481 // check if any dynamic vertex processing must occur
7482 dynamicvertex = false;
7483
7484 // we must use vertexbuffers for rendering, we can upload vertex buffers
7485 // easily enough but if the basevertex is non-zero it becomes more
7486 // difficult, so force dynamicvertex path in that case - it's suboptimal
7487 // but the most optimal case is to have the geometry sources provide their
7488 // own anyway.
7489 if (!rsurface.modelvertex3f_vertexbuffer && firstvertex != 0)
7490 dynamicvertex = true;
7491
7492 // a cvar to force the dynamic vertex path to be taken, for debugging
7494 {
7495 if (!dynamicvertex)
7496 {
7501 }
7502 dynamicvertex = true;
7503 }
7504
7505 // if there is a chance of animated vertex colors, it's a dynamic batch
7506 if ((batchneed & BATCHNEED_ARRAY_VERTEXCOLOR) && texturesurfacelist[0]->lightmapinfo)
7507 {
7508 if (!dynamicvertex)
7509 {
7514 }
7515 dynamicvertex = true;
7516 }
7517
7518 for (deformindex = 0, deform = rsurface.texture->deforms;deformindex < Q3MAXDEFORMS && deform->deform && r_deformvertexes.integer;deformindex++, deform++)
7519 {
7520 switch (deform->deform)
7521 {
7522 default:
7524 case Q3DEFORM_TEXT0:
7525 case Q3DEFORM_TEXT1:
7526 case Q3DEFORM_TEXT2:
7527 case Q3DEFORM_TEXT3:
7528 case Q3DEFORM_TEXT4:
7529 case Q3DEFORM_TEXT5:
7530 case Q3DEFORM_TEXT6:
7531 case Q3DEFORM_TEXT7:
7532 case Q3DEFORM_NONE:
7533 break;
7535 if (!dynamicvertex)
7536 {
7541 }
7542 dynamicvertex = true;
7544 break;
7546 if (!dynamicvertex)
7547 {
7552 }
7553 dynamicvertex = true;
7555 break;
7556 case Q3DEFORM_NORMAL:
7557 if (!dynamicvertex)
7558 {
7563 }
7564 dynamicvertex = true;
7566 break;
7567 case Q3DEFORM_WAVE:
7568 if(!R_TestQ3WaveFunc(deform->wavefunc, deform->waveparms))
7569 break; // if wavefunc is a nop, ignore this transform
7570 if (!dynamicvertex)
7571 {
7576 }
7577 dynamicvertex = true;
7579 break;
7580 case Q3DEFORM_BULGE:
7581 if (!dynamicvertex)
7582 {
7587 }
7588 dynamicvertex = true;
7590 break;
7591 case Q3DEFORM_MOVE:
7592 if(!R_TestQ3WaveFunc(deform->wavefunc, deform->waveparms))
7593 break; // if wavefunc is a nop, ignore this transform
7594 if (!dynamicvertex)
7595 {
7600 }
7601 dynamicvertex = true;
7603 break;
7604 }
7605 }
7607 {
7609 {
7610 default:
7611 case Q3TCGEN_TEXTURE:
7612 break;
7613 case Q3TCGEN_LIGHTMAP:
7614 if (!dynamicvertex)
7615 {
7620 }
7621 dynamicvertex = true;
7623 break;
7624 case Q3TCGEN_VECTOR:
7625 if (!dynamicvertex)
7626 {
7631 }
7632 dynamicvertex = true;
7634 break;
7636 if (!dynamicvertex)
7637 {
7642 }
7643 dynamicvertex = true;
7645 break;
7646 }
7648 {
7649 if (!dynamicvertex)
7650 {
7655 }
7656 dynamicvertex = true;
7658 }
7659 }
7660
7661 // the caller can specify BATCHNEED_NOGAPS to force a batch with
7662 // firstvertex = 0 and endvertex = numvertices (no gaps, no firstvertex),
7663 // we ensure this by treating the vertex batch as dynamic...
7664 if ((batchneed & BATCHNEED_ALWAYSCOPY) || ((batchneed & BATCHNEED_NOGAPS) && (gaps || firstvertex > 0)))
7665 {
7666 if (!dynamicvertex)
7667 {
7672 }
7673 dynamicvertex = true;
7674 }
7675
7676 // if we're going to have to apply the skeletal transform manually, we need to batch the skeletal data
7679
7718
7719 // if any dynamic vertex processing has to occur in software, we copy the
7720 // entire surface list together before processing to rebase the vertices
7721 // to start at 0 (otherwise we waste a lot of room in a vertex buffer).
7722 //
7723 // if any gaps exist and we do not have a static vertex buffer, we have to
7724 // copy the surface list together to avoid wasting upload bandwidth on the
7725 // vertices in the gaps.
7726 //
7727 // if gaps exist and we have a static vertex buffer, we can choose whether
7728 // to combine the index buffer ranges into one dynamic index buffer or
7729 // simply issue multiple glDrawElements calls (BATCHNEED_ALLOWMULTIDRAW).
7730 //
7731 // in many cases the batch is reduced to one draw call.
7732
7733 rsurface.batchmultidraw = false;
7736
7737 if (!dynamicvertex)
7738 {
7739 // static vertex data, just set pointers...
7741 // if there are gaps, we want to build a combined index buffer,
7742 // otherwise use the original static buffer with an appropriate offset
7743 if (gaps)
7744 {
7750 {
7751 rsurface.batchmultidraw = true;
7754 return;
7755 }
7756 // build a new triangle elements array for this batch
7757 rsurface.batchelement3i = (int *)R_FrameData_Alloc(batchnumtriangles * sizeof(int[3]));
7759 numtriangles = 0;
7760 for (i = 0;i < texturenumsurfaces;i++)
7761 {
7762 surfacefirsttriangle = texturesurfacelist[i]->num_firsttriangle;
7763 surfacenumtriangles = texturesurfacelist[i]->num_triangles;
7765 numtriangles += surfacenumtriangles;
7766 }
7772 if (endvertex <= 65536)
7773 {
7774 // make a 16bit (unsigned short) index array if possible
7775 rsurface.batchelement3s = (unsigned short *)R_FrameData_Alloc(batchnumtriangles * sizeof(unsigned short[3]));
7776 for (i = 0;i < numtriangles*3;i++)
7778 }
7779 }
7780 else
7781 {
7784 r_refdef.stats[r_stat_batch_fast_vertices] += batchnumvertices;
7785 r_refdef.stats[r_stat_batch_fast_triangles] += batchnumtriangles;
7786 }
7787 return;
7788 }
7789
7790 // something needs software processing, do it for real...
7791 // we only directly handle separate array data in this case and then
7792 // generate interleaved data if needed...
7796 r_refdef.stats[r_stat_batch_dynamic_vertices] += batchnumvertices;
7797 r_refdef.stats[r_stat_batch_dynamic_triangles] += batchnumtriangles;
7798
7799 // now copy the vertex data into a combined array and make an index array
7800 // (this is what Quake3 does all the time)
7801 // we also apply any skeletal animation here that would have been done in
7802 // the vertex shader, because most of the dynamic vertex animation cases
7803 // need actual vertex positions and normals
7804 //if (dynamicvertex)
7805 {
7833 rsurface.batchelement3i = (int *)R_FrameData_Alloc(batchnumtriangles * sizeof(int[3]));
7842 // we'll only be setting up certain arrays as needed
7844 rsurface.batchvertex3f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
7846 rsurface.batchnormal3f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
7848 {
7849 rsurface.batchsvector3f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
7850 rsurface.batchtvector3f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
7851 }
7853 rsurface.batchlightmapcolor4f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[4]));
7855 rsurface.batchtexcoordtexture2f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
7857 rsurface.batchtexcoordlightmap2f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
7859 {
7860 rsurface.batchskeletalindex4ub = (unsigned char *)R_FrameData_Alloc(batchnumvertices * sizeof(unsigned char[4]));
7861 rsurface.batchskeletalweight4ub = (unsigned char *)R_FrameData_Alloc(batchnumvertices * sizeof(unsigned char[4]));
7862 }
7863 numvertices = 0;
7864 numtriangles = 0;
7865 for (i = 0;i < texturenumsurfaces;i++)
7866 {
7867 surfacefirstvertex = texturesurfacelist[i]->num_firstvertex;
7868 surfacenumvertices = texturesurfacelist[i]->num_vertices;
7869 surfacefirsttriangle = texturesurfacelist[i]->num_firsttriangle;
7870 surfacenumtriangles = texturesurfacelist[i]->num_triangles;
7871 // copy only the data requested
7873 {
7875 {
7878 else
7879 memset(rsurface.batchvertex3f + 3*numvertices, 0, surfacenumvertices * sizeof(float[3]));
7880 }
7882 {
7885 else
7886 memset(rsurface.batchnormal3f + 3*numvertices, 0, surfacenumvertices * sizeof(float[3]));
7887 }
7889 {
7891 {
7894 }
7895 else
7896 {
7897 memset(rsurface.batchsvector3f + 3*numvertices, 0, surfacenumvertices * sizeof(float[3]));
7898 memset(rsurface.batchtvector3f + 3*numvertices, 0, surfacenumvertices * sizeof(float[3]));
7899 }
7900 }
7902 {
7905 else
7906 memset(rsurface.batchlightmapcolor4f + 4*numvertices, 0, surfacenumvertices * sizeof(float[4]));
7907 }
7909 {
7912 else
7913 memset(rsurface.batchtexcoordtexture2f + 2*numvertices, 0, surfacenumvertices * sizeof(float[2]));
7914 }
7916 {
7919 else
7920 memset(rsurface.batchtexcoordlightmap2f + 2*numvertices, 0, surfacenumvertices * sizeof(float[2]));
7921 }
7923 {
7925 {
7928 }
7929 else
7930 {
7931 memset(rsurface.batchskeletalindex4ub + 4*numvertices, 0, surfacenumvertices * sizeof(unsigned char[4]));
7932 memset(rsurface.batchskeletalweight4ub + 4*numvertices, 0, surfacenumvertices * sizeof(unsigned char[4]));
7933 ub = rsurface.batchskeletalweight4ub + 4*numvertices;
7934 for (j = 0;j < surfacenumvertices;j++)
7935 ub[j*4] = 255;
7936 }
7937 }
7938 }
7940 numvertices += surfacenumvertices;
7941 numtriangles += surfacenumtriangles;
7942 }
7943
7944 // generate a 16bit index array as well if possible
7945 // (in general, dynamic batches fit)
7946 if (numvertices <= 65536)
7947 {
7948 rsurface.batchelement3s = (unsigned short *)R_FrameData_Alloc(batchnumtriangles * sizeof(unsigned short[3]));
7949 for (i = 0;i < numtriangles*3;i++)
7951 }
7952
7953 // since we've copied everything, the batch now starts at 0
7955 rsurface.batchnumvertices = batchnumvertices;
7957 rsurface.batchnumtriangles = batchnumtriangles;
7958 }
7959
7960 // apply skeletal animation that would have been done in the vertex shader
7962 {
7963 const unsigned char *si;
7964 const unsigned char *sw;
7965 const float *t[4];
7966 const float *b = rsurface.batchskeletaltransform3x4;
7967 float *vp, *vs, *vt, *vn;
7968 float w[4];
7969 float m[3][4], n[3][4];
7970 float tp[3], ts[3], tt[3], tn[3];
7981 memset(m[0], 0, sizeof(m));
7982 memset(n[0], 0, sizeof(n));
7983 for (i = 0;i < batchnumvertices;i++)
7984 {
7985 t[0] = b + si[0]*12;
7986 if (sw[0] == 255)
7987 {
7988 // common case - only one matrix
7989 m[0][0] = t[0][ 0];
7990 m[0][1] = t[0][ 1];
7991 m[0][2] = t[0][ 2];
7992 m[0][3] = t[0][ 3];
7993 m[1][0] = t[0][ 4];
7994 m[1][1] = t[0][ 5];
7995 m[1][2] = t[0][ 6];
7996 m[1][3] = t[0][ 7];
7997 m[2][0] = t[0][ 8];
7998 m[2][1] = t[0][ 9];
7999 m[2][2] = t[0][10];
8000 m[2][3] = t[0][11];
8001 }
8002 else if (sw[2] + sw[3])
8003 {
8004 // blend 4 matrices
8005 t[1] = b + si[1]*12;
8006 t[2] = b + si[2]*12;
8007 t[3] = b + si[3]*12;
8008 w[0] = sw[0] * (1.0f / 255.0f);
8009 w[1] = sw[1] * (1.0f / 255.0f);
8010 w[2] = sw[2] * (1.0f / 255.0f);
8011 w[3] = sw[3] * (1.0f / 255.0f);
8012 // blend the matrices
8013 m[0][0] = t[0][ 0] * w[0] + t[1][ 0] * w[1] + t[2][ 0] * w[2] + t[3][ 0] * w[3];
8014 m[0][1] = t[0][ 1] * w[0] + t[1][ 1] * w[1] + t[2][ 1] * w[2] + t[3][ 1] * w[3];
8015 m[0][2] = t[0][ 2] * w[0] + t[1][ 2] * w[1] + t[2][ 2] * w[2] + t[3][ 2] * w[3];
8016 m[0][3] = t[0][ 3] * w[0] + t[1][ 3] * w[1] + t[2][ 3] * w[2] + t[3][ 3] * w[3];
8017 m[1][0] = t[0][ 4] * w[0] + t[1][ 4] * w[1] + t[2][ 4] * w[2] + t[3][ 4] * w[3];
8018 m[1][1] = t[0][ 5] * w[0] + t[1][ 5] * w[1] + t[2][ 5] * w[2] + t[3][ 5] * w[3];
8019 m[1][2] = t[0][ 6] * w[0] + t[1][ 6] * w[1] + t[2][ 6] * w[2] + t[3][ 6] * w[3];
8020 m[1][3] = t[0][ 7] * w[0] + t[1][ 7] * w[1] + t[2][ 7] * w[2] + t[3][ 7] * w[3];
8021 m[2][0] = t[0][ 8] * w[0] + t[1][ 8] * w[1] + t[2][ 8] * w[2] + t[3][ 8] * w[3];
8022 m[2][1] = t[0][ 9] * w[0] + t[1][ 9] * w[1] + t[2][ 9] * w[2] + t[3][ 9] * w[3];
8023 m[2][2] = t[0][10] * w[0] + t[1][10] * w[1] + t[2][10] * w[2] + t[3][10] * w[3];
8024 m[2][3] = t[0][11] * w[0] + t[1][11] * w[1] + t[2][11] * w[2] + t[3][11] * w[3];
8025 }
8026 else
8027 {
8028 // blend 2 matrices
8029 t[1] = b + si[1]*12;
8030 w[0] = sw[0] * (1.0f / 255.0f);
8031 w[1] = sw[1] * (1.0f / 255.0f);
8032 // blend the matrices
8033 m[0][0] = t[0][ 0] * w[0] + t[1][ 0] * w[1];
8034 m[0][1] = t[0][ 1] * w[0] + t[1][ 1] * w[1];
8035 m[0][2] = t[0][ 2] * w[0] + t[1][ 2] * w[1];
8036 m[0][3] = t[0][ 3] * w[0] + t[1][ 3] * w[1];
8037 m[1][0] = t[0][ 4] * w[0] + t[1][ 4] * w[1];
8038 m[1][1] = t[0][ 5] * w[0] + t[1][ 5] * w[1];
8039 m[1][2] = t[0][ 6] * w[0] + t[1][ 6] * w[1];
8040 m[1][3] = t[0][ 7] * w[0] + t[1][ 7] * w[1];
8041 m[2][0] = t[0][ 8] * w[0] + t[1][ 8] * w[1];
8042 m[2][1] = t[0][ 9] * w[0] + t[1][ 9] * w[1];
8043 m[2][2] = t[0][10] * w[0] + t[1][10] * w[1];
8044 m[2][3] = t[0][11] * w[0] + t[1][11] * w[1];
8045 }
8046 si += 4;
8047 sw += 4;
8048 // modify the vertex
8049 VectorCopy(vp, tp);
8050 vp[0] = tp[0] * m[0][0] + tp[1] * m[0][1] + tp[2] * m[0][2] + m[0][3];
8051 vp[1] = tp[0] * m[1][0] + tp[1] * m[1][1] + tp[2] * m[1][2] + m[1][3];
8052 vp[2] = tp[0] * m[2][0] + tp[1] * m[2][1] + tp[2] * m[2][2] + m[2][3];
8053 vp += 3;
8054 if (vn)
8055 {
8056 // the normal transformation matrix is a set of cross products...
8057 CrossProduct(m[1], m[2], n[0]);
8058 CrossProduct(m[2], m[0], n[1]);
8059 CrossProduct(m[0], m[1], n[2]); // is actually transpose(inverse(m)) * det(m)
8060 VectorCopy(vn, tn);
8061 vn[0] = tn[0] * n[0][0] + tn[1] * n[0][1] + tn[2] * n[0][2];
8062 vn[1] = tn[0] * n[1][0] + tn[1] * n[1][1] + tn[2] * n[1][2];
8063 vn[2] = tn[0] * n[2][0] + tn[1] * n[2][1] + tn[2] * n[2][2];
8064 VectorNormalize(vn);
8065 vn += 3;
8066 if (vs)
8067 {
8068 VectorCopy(vs, ts);
8069 vs[0] = ts[0] * n[0][0] + ts[1] * n[0][1] + ts[2] * n[0][2];
8070 vs[1] = ts[0] * n[1][0] + ts[1] * n[1][1] + ts[2] * n[1][2];
8071 vs[2] = ts[0] * n[2][0] + ts[1] * n[2][1] + ts[2] * n[2][2];
8073 vs += 3;
8074 VectorCopy(vt, tt);
8075 vt[0] = tt[0] * n[0][0] + tt[1] * n[0][1] + tt[2] * n[0][2];
8076 vt[1] = tt[0] * n[1][0] + tt[1] * n[1][1] + tt[2] * n[1][2];
8077 vt[2] = tt[0] * n[2][0] + tt[1] * n[2][1] + tt[2] * n[2][2];
8078 VectorNormalize(vt);
8079 vt += 3;
8080 }
8081 }
8082 }
8085 }
8086
8087 // q1bsp surfaces rendered in vertex color mode have to have colors
8088 // calculated based on lightstyles
8089 if ((batchneed & BATCHNEED_ARRAY_VERTEXCOLOR) && texturesurfacelist[0]->lightmapinfo)
8090 {
8091 // generate color arrays for the surfaces in this list
8092 int c[4];
8093 int scale;
8094 int size3;
8095 const int *offsets;
8096 const unsigned char *lm;
8097 rsurface.batchlightmapcolor4f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[4]));
8100 numvertices = 0;
8101 for (i = 0;i < texturenumsurfaces;i++)
8102 {
8104 offsets = rsurface.modellightmapoffsets + surface->num_firstvertex;
8105 surfacenumvertices = surface->num_vertices;
8106 if (surface->lightmapinfo->samples)
8107 {
8108 for (j = 0;j < surfacenumvertices;j++)
8109 {
8110 lm = surface->lightmapinfo->samples + offsets[j];
8111 scale = r_refdef.scene.lightstylevalue[surface->lightmapinfo->styles[0]];
8112 VectorScale(lm, scale, c);
8113 if (surface->lightmapinfo->styles[1] != 255)
8114 {
8115 size3 = ((surface->lightmapinfo->extents[0]>>4)+1)*((surface->lightmapinfo->extents[1]>>4)+1)*3;
8116 lm += size3;
8117 scale = r_refdef.scene.lightstylevalue[surface->lightmapinfo->styles[1]];
8118 VectorMA(c, scale, lm, c);
8119 if (surface->lightmapinfo->styles[2] != 255)
8120 {
8121 lm += size3;
8122 scale = r_refdef.scene.lightstylevalue[surface->lightmapinfo->styles[2]];
8123 VectorMA(c, scale, lm, c);
8124 if (surface->lightmapinfo->styles[3] != 255)
8125 {
8126 lm += size3;
8127 scale = r_refdef.scene.lightstylevalue[surface->lightmapinfo->styles[3]];
8128 VectorMA(c, scale, lm, c);
8129 }
8130 }
8131 }
8132 c[0] >>= 7;
8133 c[1] >>= 7;
8134 c[2] >>= 7;
8135 Vector4Set(rsurface.batchlightmapcolor4f + 4*numvertices, min(c[0], 255) * (1.0f / 255.0f), min(c[1], 255) * (1.0f / 255.0f), min(c[2], 255) * (1.0f / 255.0f), 1);
8136 numvertices++;
8137 }
8138 }
8139 else
8140 {
8141 for (j = 0;j < surfacenumvertices;j++)
8142 {
8143 Vector4Set(rsurface.batchlightmapcolor4f + 4*numvertices, 0, 0, 0, 1);
8144 numvertices++;
8145 }
8146 }
8147 }
8148 }
8149
8150 // if vertices are deformed (sprite flares and things in maps, possibly
8151 // water waves, bulges and other deformations), modify the copied vertices
8152 // in place
8153 for (deformindex = 0, deform = rsurface.texture->deforms;deformindex < Q3MAXDEFORMS && deform->deform && r_deformvertexes.integer;deformindex++, deform++)
8154 {
8155 float scale;
8156 switch (deform->deform)
8157 {
8158 default:
8160 case Q3DEFORM_TEXT0:
8161 case Q3DEFORM_TEXT1:
8162 case Q3DEFORM_TEXT2:
8163 case Q3DEFORM_TEXT3:
8164 case Q3DEFORM_TEXT4:
8165 case Q3DEFORM_TEXT5:
8166 case Q3DEFORM_TEXT6:
8167 case Q3DEFORM_TEXT7:
8168 case Q3DEFORM_NONE:
8169 break;
8177// rsurface.batchvertex3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f);
8178// rsurface.batchvertex3f_vertexbuffer = NULL;
8179// rsurface.batchvertex3f_bufferoffset = 0;
8180// rsurface.batchsvector3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchsvector3f);
8181// rsurface.batchsvector3f_vertexbuffer = NULL;
8182// rsurface.batchsvector3f_bufferoffset = 0;
8183// rsurface.batchtvector3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchtvector3f);
8184// rsurface.batchtvector3f_vertexbuffer = NULL;
8185// rsurface.batchtvector3f_bufferoffset = 0;
8186// rsurface.batchnormal3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f);
8187// rsurface.batchnormal3f_vertexbuffer = NULL;
8188// rsurface.batchnormal3f_bufferoffset = 0;
8189 // sometimes we're on a renderpath that does not use vectors (GL11/GL13/GLES1)
8194 // a single autosprite surface can contain multiple sprites...
8195 for (j = 0;j < batchnumvertices - 3;j += 4)
8196 {
8197 VectorClear(center);
8198 for (i = 0;i < 4;i++)
8199 VectorAdd(center, rsurface.batchvertex3f + 3*(j+i), center);
8200 VectorScale(center, 0.25f, center);
8204 for (i = 0;i < 4;i++)
8205 {
8206 VectorSubtract(rsurface.batchvertex3f + 3*(j+i), center, v);
8208 }
8209 }
8210 // if we get here, BATCHNEED_ARRAY_NORMAL and BATCHNEED_ARRAY_VECTOR are in batchneed, so no need to check
8213 break;
8221// rsurface.batchvertex3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f);
8222// rsurface.batchvertex3f_vertexbuffer = NULL;
8223// rsurface.batchvertex3f_bufferoffset = 0;
8224 {
8225 const float *v1, *v2;
8226 vec3_t start, end;
8227 float f, l;
8228 struct
8229 {
8230 float length2;
8231 const float *v1;
8232 const float *v2;
8233 }
8234 shortest[2];
8235 memset(shortest, 0, sizeof(shortest));
8236 // a single autosprite surface can contain multiple sprites...
8237 for (j = 0;j < batchnumvertices - 3;j += 4)
8238 {
8239 VectorClear(center);
8240 for (i = 0;i < 4;i++)
8241 VectorAdd(center, rsurface.batchvertex3f + 3*(j+i), center);
8242 VectorScale(center, 0.25f, center);
8243 // find the two shortest edges, then use them to define the
8244 // axis vectors for rotating around the central axis
8245 for (i = 0;i < 6;i++)
8246 {
8247 v1 = rsurface.batchvertex3f + 3*(j+quadedges[i][0]);
8248 v2 = rsurface.batchvertex3f + 3*(j+quadedges[i][1]);
8249 l = VectorDistance2(v1, v2);
8250 // this length bias tries to make sense of square polygons, assuming they are meant to be upright
8251 if (v1[2] != v2[2])
8252 l += (1.0f / 1024.0f);
8253 if (shortest[0].length2 > l || i == 0)
8254 {
8255 shortest[1] = shortest[0];
8256 shortest[0].length2 = l;
8257 shortest[0].v1 = v1;
8258 shortest[0].v2 = v2;
8259 }
8260 else if (shortest[1].length2 > l || i == 1)
8261 {
8262 shortest[1].length2 = l;
8263 shortest[1].v1 = v1;
8264 shortest[1].v2 = v2;
8265 }
8266 }
8267 VectorLerp(shortest[0].v1, 0.5f, shortest[0].v2, start);
8268 VectorLerp(shortest[1].v1, 0.5f, shortest[1].v2, end);
8269 // this calculates the right vector from the shortest edge
8270 // and the up vector from the edge midpoints
8273 VectorSubtract(end, start, up);
8275 // calculate a forward vector to use instead of the original plane normal (this is how we get a new right vector)
8277 //Matrix4x4_Transform3x3(&rsurface.inversematrix, r_refdef.view.forward, forward);
8283 // rotate the quad around the up axis vector, this is made
8284 // especially easy by the fact we know the quad is flat,
8285 // so we only have to subtract the center position and
8286 // measure distance along the right vector, and then
8287 // multiply that by the newright vector and add back the
8288 // center position
8289 // we also need to subtract the old position to undo the
8290 // displacement from the center, which we do with a
8291 // DotProduct, the subtraction/addition of center is also
8292 // optimized into DotProducts here
8293 l = DotProduct(right, center);
8294 for (i = 0;i < 4;i++)
8295 {
8296 v1 = rsurface.batchvertex3f + 3*(j+i);
8297 f = DotProduct(right, v1) - l;
8299 }
8300 }
8301 }
8302 if(batchneed & (BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR)) // otherwise these can stay NULL
8303 {
8304// rsurface.batchnormal3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
8305// rsurface.batchnormal3f_vertexbuffer = NULL;
8306// rsurface.batchnormal3f_bufferoffset = 0;
8308 }
8309 if(batchneed & BATCHNEED_ARRAY_VECTOR) // otherwise these can stay NULL
8310 {
8311// rsurface.batchsvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
8312// rsurface.batchsvector3f_vertexbuffer = NULL;
8313// rsurface.batchsvector3f_bufferoffset = 0;
8314// rsurface.batchtvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
8315// rsurface.batchtvector3f_vertexbuffer = NULL;
8316// rsurface.batchtvector3f_bufferoffset = 0;
8318 }
8319 break;
8320 case Q3DEFORM_NORMAL:
8321 // deform the normals to make reflections wavey
8322 rsurface.batchnormal3f = (float *)R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f);
8325 for (j = 0;j < batchnumvertices;j++)
8326 {
8327 float vertex[3];
8328 float *normal = rsurface.batchnormal3f + 3*j;
8329 VectorScale(rsurface.batchvertex3f + 3*j, 0.98f, vertex);
8330 normal[0] = rsurface.batchnormal3f[j*3+0] + deform->parms[0] * noise4f( vertex[0], vertex[1], vertex[2], rsurface.shadertime * deform->parms[1]);
8331 normal[1] = rsurface.batchnormal3f[j*3+1] + deform->parms[0] * noise4f( 98 + vertex[0], vertex[1], vertex[2], rsurface.shadertime * deform->parms[1]);
8332 normal[2] = rsurface.batchnormal3f[j*3+2] + deform->parms[0] * noise4f(196 + vertex[0], vertex[1], vertex[2], rsurface.shadertime * deform->parms[1]);
8334 }
8335 if(batchneed & BATCHNEED_ARRAY_VECTOR) // otherwise these can stay NULL
8336 {
8337// rsurface.batchsvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
8338// rsurface.batchsvector3f_vertexbuffer = NULL;
8339// rsurface.batchsvector3f_bufferoffset = 0;
8340// rsurface.batchtvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
8341// rsurface.batchtvector3f_vertexbuffer = NULL;
8342// rsurface.batchtvector3f_bufferoffset = 0;
8344 }
8345 break;
8346 case Q3DEFORM_WAVE:
8347 // deform vertex array to make wavey water and flags and such
8348 waveparms[0] = deform->waveparms[0];
8349 waveparms[1] = deform->waveparms[1];
8350 waveparms[2] = deform->waveparms[2];
8351 waveparms[3] = deform->waveparms[3];
8352 if(!R_TestQ3WaveFunc(deform->wavefunc, waveparms))
8353 break; // if wavefunc is a nop, don't make a dynamic vertex array
8354 // this is how a divisor of vertex influence on deformation
8355 animpos = deform->parms[0] ? 1.0f / deform->parms[0] : 100.0f;
8356 scale = R_EvaluateQ3WaveFunc(deform->wavefunc, waveparms);
8357// rsurface.batchvertex3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f);
8358// rsurface.batchvertex3f_vertexbuffer = NULL;
8359// rsurface.batchvertex3f_bufferoffset = 0;
8360// rsurface.batchnormal3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f);
8361// rsurface.batchnormal3f_vertexbuffer = NULL;
8362// rsurface.batchnormal3f_bufferoffset = 0;
8363 for (j = 0;j < batchnumvertices;j++)
8364 {
8365 // if the wavefunc depends on time, evaluate it per-vertex
8366 if (waveparms[3])
8367 {
8368 waveparms[2] = deform->waveparms[2] + (rsurface.batchvertex3f[j*3+0] + rsurface.batchvertex3f[j*3+1] + rsurface.batchvertex3f[j*3+2]) * animpos;
8369 scale = R_EvaluateQ3WaveFunc(deform->wavefunc, waveparms);
8370 }
8372 }
8373 // if we get here, BATCHNEED_ARRAY_NORMAL is in batchneed, so no need to check
8375 if(batchneed & BATCHNEED_ARRAY_VECTOR) // otherwise these can stay NULL
8376 {
8377// rsurface.batchsvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
8378// rsurface.batchsvector3f_vertexbuffer = NULL;
8379// rsurface.batchsvector3f_bufferoffset = 0;
8380// rsurface.batchtvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
8381// rsurface.batchtvector3f_vertexbuffer = NULL;
8382// rsurface.batchtvector3f_bufferoffset = 0;
8384 }
8385 break;
8386 case Q3DEFORM_BULGE:
8387 // deform vertex array to make the surface have moving bulges
8388// rsurface.batchvertex3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f);
8389// rsurface.batchvertex3f_vertexbuffer = NULL;
8390// rsurface.batchvertex3f_bufferoffset = 0;
8391// rsurface.batchnormal3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchnormal3f);
8392// rsurface.batchnormal3f_vertexbuffer = NULL;
8393// rsurface.batchnormal3f_bufferoffset = 0;
8394 for (j = 0;j < batchnumvertices;j++)
8395 {
8396 scale = sin(rsurface.batchtexcoordtexture2f[j*2+0] * deform->parms[0] + rsurface.shadertime * deform->parms[2]) * deform->parms[1];
8398 }
8399 // if we get here, BATCHNEED_ARRAY_NORMAL is in batchneed, so no need to check
8401 if(batchneed & BATCHNEED_ARRAY_VECTOR) // otherwise these can stay NULL
8402 {
8403// rsurface.batchsvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
8404// rsurface.batchsvector3f_vertexbuffer = NULL;
8405// rsurface.batchsvector3f_bufferoffset = 0;
8406// rsurface.batchtvector3f = R_FrameData_Alloc(batchnumvertices * sizeof(float[3]));
8407// rsurface.batchtvector3f_vertexbuffer = NULL;
8408// rsurface.batchtvector3f_bufferoffset = 0;
8410 }
8411 break;
8412 case Q3DEFORM_MOVE:
8413 // deform vertex array
8414 if(!R_TestQ3WaveFunc(deform->wavefunc, deform->waveparms))
8415 break; // if wavefunc is a nop, don't make a dynamic vertex array
8416 scale = R_EvaluateQ3WaveFunc(deform->wavefunc, deform->waveparms);
8417 VectorScale(deform->parms, scale, waveparms);
8418// rsurface.batchvertex3f = R_FrameData_Store(batchnumvertices * sizeof(float[3]), rsurface.batchvertex3f);
8419// rsurface.batchvertex3f_vertexbuffer = NULL;
8420// rsurface.batchvertex3f_bufferoffset = 0;
8421 for (j = 0;j < batchnumvertices;j++)
8423 break;
8424 }
8425 }
8426
8428 {
8429 // generate texcoords based on the chosen texcoord source
8431 {
8432 default:
8433 case Q3TCGEN_TEXTURE:
8434 break;
8435 case Q3TCGEN_LIGHTMAP:
8436 // rsurface.batchtexcoordtexture2f = R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
8437 // rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
8438 // rsurface.batchtexcoordtexture2f_bufferoffset = 0;
8440 memcpy(rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordlightmap2f, batchnumvertices * sizeof(float[2]));
8441 break;
8442 case Q3TCGEN_VECTOR:
8443 // rsurface.batchtexcoordtexture2f = R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
8444 // rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
8445 // rsurface.batchtexcoordtexture2f_bufferoffset = 0;
8446 for (j = 0;j < batchnumvertices;j++)
8447 {
8450 }
8451 break;
8453 // make environment reflections using a spheremap
8454 rsurface.batchtexcoordtexture2f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
8457 for (j = 0;j < batchnumvertices;j++)
8458 {
8459 // identical to Q3A's method, but executed in worldspace so
8460 // carried models can be shiny too
8461
8462 float viewer[3], d, reflected[3], worldreflected[3];
8463
8465 // VectorNormalize(viewer);
8466
8468
8469 reflected[0] = rsurface.batchnormal3f[j*3+0]*2*d - viewer[0];
8470 reflected[1] = rsurface.batchnormal3f[j*3+1]*2*d - viewer[1];
8471 reflected[2] = rsurface.batchnormal3f[j*3+2]*2*d - viewer[2];
8472 // note: this is proportinal to viewer, so we can normalize later
8473
8476
8477 // note: this sphere map only uses world x and z!
8478 // so positive and negative y will LOOK THE SAME.
8479 rsurface.batchtexcoordtexture2f[j*2+0] = 0.5 + 0.5 * worldreflected[1];
8480 rsurface.batchtexcoordtexture2f[j*2+1] = 0.5 - 0.5 * worldreflected[2];
8481 }
8482 break;
8483 }
8484 // the only tcmod that needs software vertex processing is turbulent, so
8485 // check for it here and apply the changes if needed
8486 // and we only support that as the first one
8487 // (handling a mixture of turbulent and other tcmods would be problematic
8488 // without punting it entirely to a software path)
8490 {
8493 // rsurface.batchtexcoordtexture2f = R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
8494 // rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
8495 // rsurface.batchtexcoordtexture2f_bufferoffset = 0;
8496 for (j = 0;j < batchnumvertices;j++)
8497 {
8498 rsurface.batchtexcoordtexture2f[j*2+0] += amplitude * sin(((rsurface.batchvertex3f[j*3+0] + rsurface.batchvertex3f[j*3+2]) * 1.0 / 1024.0f + animpos) * M_PI * 2);
8499 rsurface.batchtexcoordtexture2f[j*2+1] += amplitude * sin(((rsurface.batchvertex3f[j*3+1] ) * 1.0 / 1024.0f + animpos) * M_PI * 2);
8500 }
8501 }
8502 }
8503}
8504
8506{
8507 // sometimes a zero triangle surface (usually a degenerate patch) makes it
8508 // through the pipeline, killing it earlier in the pipeline would have
8509 // per-surface overhead rather than per-batch overhead, so it's best to
8510 // reject it here, before it hits glDraw.
8511 if (rsurface.batchnumtriangles == 0)
8512 return;
8513#if 0
8514 // batch debugging code
8516 {
8517 int i;
8518 int j;
8519 int c;
8520 const int *e;
8522 for (i = 0;i < rsurface.batchnumtriangles*3;i++)
8523 {
8524 c = e[i];
8525 for (j = 0;j < rsurface.entity->model->num_surfaces;j++)
8526 {
8528 {
8530 Sys_Error("RSurf_DrawBatch: index %i uses different texture (%s) than surface %i which it belongs to (which uses %s)\n", c, rsurface.texture->name, j, rsurface.modelsurfaces[j].texture->name);
8531 break;
8532 }
8533 }
8534 }
8535 }
8536#endif
8538 {
8539 // issue multiple draws rather than copying index data
8540 int numsurfaces = rsurface.batchmultidrawnumsurfaces;
8541 const msurface_t **surfacelist = rsurface.batchmultidrawsurfacelist;
8542 int i, j, k, firstvertex, endvertex, firsttriangle, endtriangle;
8543 for (i = 0;i < numsurfaces;)
8544 {
8545 // combine consecutive surfaces as one draw
8546 for (k = i, j = i + 1;j < numsurfaces;k = j, j++)
8547 if (surfacelist[j] != surfacelist[k] + 1)
8548 break;
8549 firstvertex = surfacelist[i]->num_firstvertex;
8550 endvertex = surfacelist[k]->num_firstvertex + surfacelist[k]->num_vertices;
8551 firsttriangle = surfacelist[i]->num_firsttriangle;
8552 endtriangle = surfacelist[k]->num_firsttriangle + surfacelist[k]->num_triangles;
8554 i = j;
8555 }
8556 }
8557 else
8558 {
8559 // there is only one consecutive run of index data (may have been combined)
8561 }
8562}
8563
8565{
8566 // pick the closest matching water plane
8567 int planeindex, vertexindex, bestplaneindex = -1;
8568 float d, bestd;
8569 vec3_t vert;
8570 const float *v;
8572 qbool prepared = false;
8573 bestd = 0;
8574 for (planeindex = 0, p = r_fb.water.waterplanes;planeindex < r_fb.water.numwaterplanes;planeindex++, p++)
8575 {
8577 continue;
8578 d = 0;
8579 if(!prepared)
8580 {
8582 prepared = true;
8583 if(rsurface.batchnumvertices == 0)
8584 break;
8585 }
8587 {
8589 d += fabs(PlaneDiff(vert, &p->plane));
8590 }
8591 if (bestd > d || bestplaneindex < 0)
8592 {
8593 bestd = d;
8594 bestplaneindex = planeindex;
8595 }
8596 }
8597 return bestplaneindex;
8598 // NOTE: this MAY return a totally unrelated water plane; we can ignore
8599 // this situation though, as it might be better to render single larger
8600 // batches with useless stuff (backface culled for example) than to
8601 // render multiple smaller batches
8602}
8603
8605{
8606 // submodels are biased to avoid z-fighting with world surfaces that they
8607 // may be exactly overlapping (avoids z-fighting artifacts on certain
8608 // doors and things in Quake maps)
8613}
8614
8616{
8617 int j;
8618 const float *v;
8619 float p[3], mins[3], maxs[3];
8620 int scissor[4];
8621 // transparent sky would be ridiculous
8623 return;
8624 R_SetupShader_Generic_NoTexture(false, false);
8625 skyrenderlater = true;
8627 GL_DepthMask(true);
8628
8629 // add the vertices of the surfaces to a world bounding box so we can scissor the sky render later
8631 {
8634 {
8636 if (j > 0)
8637 {
8638 if (mins[0] > p[0]) mins[0] = p[0];
8639 if (mins[1] > p[1]) mins[1] = p[1];
8640 if (mins[2] > p[2]) mins[2] = p[2];
8641 if (maxs[0] < p[0]) maxs[0] = p[0];
8642 if (maxs[1] < p[1]) maxs[1] = p[1];
8643 if (maxs[2] < p[2]) maxs[2] = p[2];
8644 }
8645 else
8646 {
8647 VectorCopy(p, mins);
8648 VectorCopy(p, maxs);
8649 }
8650 }
8651 if (!R_ScissorForBBox(mins, maxs, scissor))
8652 {
8653 if (skyscissor[2])
8654 {
8655 if (skyscissor[0] > scissor[0])
8656 {
8657 skyscissor[2] += skyscissor[0] - scissor[0];
8658 skyscissor[0] = scissor[0];
8659 }
8660 if (skyscissor[1] > scissor[1])
8661 {
8662 skyscissor[3] += skyscissor[1] - scissor[1];
8663 skyscissor[1] = scissor[1];
8664 }
8665 if (skyscissor[0] + skyscissor[2] < scissor[0] + scissor[2])
8666 skyscissor[2] = scissor[0] + scissor[2] - skyscissor[0];
8667 if (skyscissor[1] + skyscissor[3] < scissor[1] + scissor[3])
8668 skyscissor[3] = scissor[1] + scissor[3] - skyscissor[1];
8669 }
8670 else
8672 }
8673 }
8674
8675 // LadyHavoc: HalfLife maps have freaky skypolys so don't use
8676 // skymasking on them, and Quake3 never did sky masking (unlike
8677 // software Quake and software Quake2), so disable the sky masking
8678 // in Quake3 maps as it causes problems with q3map2 sky tricks,
8679 // and skymasking also looks very bad when noclipping outside the
8680 // level, so don't use it then either.
8682 {
8684 if (skyrendermasked)
8685 {
8686 R_SetupShader_DepthOrShadow(false, false, false);
8687 // depth-only (masking)
8688 GL_ColorMask(0, 0, 0, 0);
8689 // just to make sure that braindead drivers don't draw
8690 // anything despite that colormask...
8694 }
8695 else
8696 {
8697 R_SetupShader_Generic_NoTexture(false, false);
8698 // fog sky
8703 }
8705 if (skyrendermasked)
8707 }
8709 GL_Color(1, 1, 1, 1);
8710}
8711
8715{
8717 return;
8718 if (prepass)
8719 {
8720 // render screenspace normalmap to texture
8721 GL_DepthMask(true);
8724 return;
8725 }
8726
8727 // bind lightmap texture
8728
8729 // water/refraction/reflection/camera surfaces have to be handled specially
8731 {
8732 int start, end, startplaneindex;
8733 for (start = 0;start < texturenumsurfaces;start = end)
8734 {
8736 if(startplaneindex < 0)
8737 {
8738 // this happens if the plane e.g. got backface culled and thus didn't get a water plane. We can just ignore this.
8739 // Con_Printf("No matching water plane for surface with material flags 0x%08x - PLEASE DEBUG THIS\n", rsurface.texture->currentmaterialflags);
8740 end = start + 1;
8741 continue;
8742 }
8743 for (end = start + 1;end < texturenumsurfaces && startplaneindex == RSurf_FindWaterPlaneForSurface(texturesurfacelist[end]);end++)
8744 ;
8745 // now that we have a batch using the same planeindex, render it
8747 {
8748 // render water or distortion background
8749 GL_DepthMask(true);
8752 // blend surface on top
8753 GL_DepthMask(false);
8756 }
8758 {
8759 // render surface with reflection texture as input
8763 }
8764 }
8765 return;
8766 }
8767
8768 // render surface batch normally
8772}
8773
8775{
8776 int vi;
8777 int j;
8779 int k;
8780 const msurface_t *surface;
8781 float surfacecolor4f[4];
8782 float c[4];
8784
8785// R_Mesh_ResetTextureState();
8786 R_SetupShader_Generic_NoTexture(false, false);
8787
8790
8791 switch (r_showsurfaces.integer)
8792 {
8793 case 1:
8794 default:
8796 vi = 0;
8798 {
8800 k = (int)(((size_t)surface) / sizeof(msurface_t));
8801 Vector4Set(surfacecolor4f, (k & 0xF) * (1.0f / 16.0f), (k & 0xF0) * (1.0f / 256.0f), (k & 0xF00) * (1.0f / 4096.0f), 1);
8802 for (j = 0;j < surface->num_vertices;j++)
8803 {
8805 vi++;
8806 }
8807 }
8808 break;
8809 case 3:
8810 if(t && t->currentskinframe)
8811 {
8812 Vector4Copy(t->currentskinframe->avgcolor, c);
8813 c[3] *= t->currentalpha;
8814 }
8815 else
8816 {
8817 Vector4Set(c, 1, 0, 1, 1);
8818 }
8819 if (t && (t->pantstexture || t->shirttexture))
8820 {
8822 }
8825 c[3] *= r_wateralpha.value;
8827 vi = 0;
8829 {
8831 {
8833 for (j = 0;j < surface->num_vertices;j++)
8834 {
8835 float *ptr = rsurface.batchlightmapcolor4f + 4 * vi;
8836 Vector4Multiply(ptr, c, ptr);
8837 vi++;
8838 }
8839 }
8840 }
8841 else
8842 {
8844 {
8846 for (j = 0;j < surface->num_vertices;j++)
8847 {
8848 float *ptr = rsurface.batchlightmapcolor4f + 4 * vi;
8849 Vector4Copy(c, ptr);
8850 vi++;
8851 }
8852 }
8853 }
8854 break;
8855 }
8858}
8859
8878
8879static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
8880{
8881 int i, j;
8884 const msurface_t *surface;
8886
8887 RSurf_ActiveModelEntity(ent, true, true, false);
8888
8890 {
8891 qbool setup = false;
8892 for (i = 0;i < numsurfaces;i = j)
8893 {
8894 j = i + 1;
8895 surface = rsurface.modelsurfaces + surfacelist[i];
8901 // scan ahead until we find a different texture
8902 endsurface = min(i + 1024, numsurfaces);
8905 for (;j < endsurface;j++)
8906 {
8907 surface = rsurface.modelsurfaces + surfacelist[j];
8908 if (texture != surface->texture)
8909 break;
8911 }
8913 continue;
8914 // render the range of surfaces as depth
8915 if (!setup)
8916 {
8917 setup = true;
8918 GL_ColorMask(0,0,0,0);
8919 GL_Color(1,1,1,1);
8920 GL_DepthTest(true);
8922 GL_DepthMask(true);
8923// R_Mesh_ResetTextureState();
8924 }
8930 }
8931 if (setup)
8933 }
8934
8935 for (i = 0;i < numsurfaces;i = j)
8936 {
8937 j = i + 1;
8938 surface = rsurface.modelsurfaces + surfacelist[i];
8941 // scan ahead until we find a different texture
8945 rsurface.lightmaptexture = surface->lightmaptexture;
8946 rsurface.deluxemaptexture = surface->deluxemaptexture;
8947 rsurface.uselightmaptexture = surface->lightmaptexture != NULL;
8948 for (;j < endsurface;j++)
8949 {
8950 surface = rsurface.modelsurfaces + surfacelist[j];
8951 if (texture != surface->texture || rsurface.lightmaptexture != surface->lightmaptexture)
8952 break;
8954 }
8955 // render the range of surfaces
8957 }
8958 rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity
8959}
8960
8962{
8963 // transparent surfaces get pushed off into the transparent queue
8964 int surfacelistindex;
8965 const msurface_t *surface;
8966 vec3_t tempcenter, center;
8968 {
8971 {
8972 tempcenter[0] = bound(surface->mins[0], rsurface.localvieworigin[0], surface->maxs[0]);
8973 tempcenter[1] = bound(surface->mins[1], rsurface.localvieworigin[1], surface->maxs[1]);
8974 tempcenter[2] = bound(surface->mins[2], rsurface.localvieworigin[2], surface->maxs[2]);
8975 }
8976 else
8977 {
8978 tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f;
8979 tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f;
8980 tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f;
8981 }
8983 if (rsurface.entity->transparent_offset) // transparent offset
8984 {
8988 }
8990 }
8991}
8992
9005
9007{
9009 if (ui)
9011 else if (depthonly)
9013 else if (prepass)
9014 {
9016 return;
9019 else
9021 }
9025 return;
9027 {
9028 // in the deferred case, transparent surfaces were queued during prepass
9031 }
9032 else
9033 {
9034 // the alphatest check is to make sure we write depth for anything we skipped on the depth-only pass earlier
9036 }
9038}
9039
9040static void R_QueueModelSurfaceList(entity_render_t *ent, int numsurfaces, const msurface_t **surfacelist, int flagsmask, qbool writedepth, qbool depthonly, qbool prepass, qbool ui)
9041{
9042 int i, j;
9045 // break the surface list down into batches by texture and use of lightmapping
9046 for (i = 0;i < numsurfaces;i = j)
9047 {
9048 j = i + 1;
9049 // texture is the base texture pointer, rsurface.texture is the
9050 // current frame/skin the texture is directing us to use (for example
9051 // if a model has 2 skins and it is on skin 1, then skin 0 tells us to
9052 // use skin 1 instead)
9053 texture = surfacelist[i]->texture;
9056 {
9057 // if this texture is not the kind we want, skip ahead to the next one
9058 for (;j < numsurfaces && texture == surfacelist[j]->texture;j++)
9059 ;
9060 continue;
9061 }
9062 if(depthonly || prepass)
9063 {
9067 // simply scan ahead until we find a different texture or lightmap state
9068 for (;j < numsurfaces && texture == surfacelist[j]->texture;j++)
9069 ;
9070 }
9071 else
9072 {
9073 rsurface.lightmaptexture = surfacelist[i]->lightmaptexture;
9076 // simply scan ahead until we find a different texture or lightmap state
9077 for (;j < numsurfaces && texture == surfacelist[j]->texture && rsurface.lightmaptexture == surfacelist[j]->lightmaptexture;j++)
9078 ;
9079 }
9080 // render the range of surfaces
9082 }
9084}
9085
9086float locboxvertex3f[6*4*3] =
9087{
9088 1,0,1, 1,0,0, 1,1,0, 1,1,1,
9089 0,1,1, 0,1,0, 0,0,0, 0,0,1,
9090 1,1,1, 1,1,0, 0,1,0, 0,1,1,
9091 0,0,1, 0,0,0, 1,0,0, 1,0,1,
9092 0,0,1, 1,0,1, 1,1,1, 0,1,1,
9093 1,0,0, 0,0,0, 0,1,0, 1,1,0
9094};
9095
9096unsigned short locboxelements[6*2*3] =
9097{
9098 0, 1, 2, 0, 2, 3,
9099 4, 5, 6, 4, 6, 7,
9100 8, 9,10, 8,10,11,
9101 12,13,14, 12,14,15,
9102 16,17,18, 16,18,19,
9103 20,21,22, 20,22,23
9104};
9105
9106static void R_DrawLoc_Callback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
9107{
9108 int i, j;
9109 cl_locnode_t *loc = (cl_locnode_t *)ent;
9110 vec3_t mins, size;
9111 float vertex3f[6*4*3];
9114 GL_DepthMask(false);
9115 GL_DepthRange(0, 1);
9117 GL_DepthTest(true);
9120
9121// R_Mesh_ResetTextureState();
9122
9123 i = surfacelist[0];
9124 GL_Color(((i & 0x0007) >> 0) * (1.0f / 7.0f) * r_refdef.view.colorscale,
9125 ((i & 0x0038) >> 3) * (1.0f / 7.0f) * r_refdef.view.colorscale,
9126 ((i & 0x01C0) >> 6) * (1.0f / 7.0f) * r_refdef.view.colorscale,
9127 surfacelist[0] < 0 ? 0.5f : 0.125f);
9128
9129 if (VectorCompare(loc->mins, loc->maxs))
9130 {
9131 VectorSet(size, 2, 2, 2);
9132 VectorMA(loc->mins, -0.5f, size, mins);
9133 }
9134 else
9135 {
9136 VectorCopy(loc->mins, mins);
9137 VectorSubtract(loc->maxs, loc->mins, size);
9138 }
9139
9140 for (i = 0;i < 6*4*3;)
9141 for (j = 0;j < 3;j++, i++)
9142 vertex3f[i] = mins[j] + size[j] * locboxvertex3f[i];
9143
9145 R_SetupShader_Generic_NoTexture(false, false);
9146 R_Mesh_Draw(0, 6*4, 0, 6*2, NULL, NULL, 0, locboxelements, NULL, 0);
9147}
9148
9149void R_DrawLocs(void)
9150{
9151 int index;
9153 vec3_t center;
9155 for (loc = cl.locnodes, index = 0;loc;loc = loc->next, index++)
9156 {
9157 VectorLerp(loc->mins, 0.5f, loc->maxs, center);
9159 }
9160}
9161
9163{
9164 if (decalsystem->decals)
9165 Mem_Free(decalsystem->decals);
9166 memset(decalsystem, 0, sizeof(*decalsystem));
9167}
9168
9169static void R_DecalSystem_SpawnTriangle(decalsystem_t *decalsystem, const float *v0, const float *v1, const float *v2, const float *t0, const float *t1, const float *t2, const float *c0, const float *c1, const float *c2, int triangleindex, int surfaceindex, unsigned int decalsequence)
9170{
9172 tridecal_t *decals;
9173 int i;
9174
9175 // expand or initialize the system
9176 if (decalsystem->maxdecals <= decalsystem->numdecals)
9177 {
9178 decalsystem_t old = *decalsystem;
9180 decalsystem->maxdecals = max(16, decalsystem->maxdecals * 2);
9181 useshortelements = decalsystem->maxdecals * 3 <= 65536;
9182 decalsystem->decals = (tridecal_t *)Mem_Alloc(cls.levelmempool, decalsystem->maxdecals * (sizeof(tridecal_t) + sizeof(float[3][3]) + sizeof(float[3][2]) + sizeof(float[3][4]) + sizeof(int[3]) + (useshortelements ? sizeof(unsigned short[3]) : 0)));
9183 decalsystem->color4f = (float *)(decalsystem->decals + decalsystem->maxdecals);
9184 decalsystem->texcoord2f = (float *)(decalsystem->color4f + decalsystem->maxdecals*12);
9185 decalsystem->vertex3f = (float *)(decalsystem->texcoord2f + decalsystem->maxdecals*6);
9186 decalsystem->element3i = (int *)(decalsystem->vertex3f + decalsystem->maxdecals*9);
9187 decalsystem->element3s = (useshortelements ? ((unsigned short *)(decalsystem->element3i + decalsystem->maxdecals*3)) : NULL);
9188 if (decalsystem->numdecals)
9189 memcpy(decalsystem->decals, old.decals, decalsystem->numdecals * sizeof(tridecal_t));
9190 if (old.decals)
9191 Mem_Free(old.decals);
9192 for (i = 0;i < decalsystem->maxdecals*3;i++)
9193 decalsystem->element3i[i] = i;
9194 if (useshortelements)
9195 for (i = 0;i < decalsystem->maxdecals*3;i++)
9196 decalsystem->element3s[i] = i;
9197 }
9198
9199 // grab a decal and search for another free slot for the next one
9200 decals = decalsystem->decals;
9201 decal = decalsystem->decals + (i = decalsystem->freedecal++);
9202 for (i = decalsystem->freedecal;i < decalsystem->numdecals && decals[i].color4f[0][3];i++)
9203 ;
9204 decalsystem->freedecal = i;
9205 if (decalsystem->numdecals <= i)
9206 decalsystem->numdecals = i + 1;
9207
9208 // initialize the decal
9209 decal->lived = 0;
9210 decal->triangleindex = triangleindex;
9211 decal->surfaceindex = surfaceindex;
9212 decal->decalsequence = decalsequence;
9213 decal->color4f[0][0] = c0[0];
9214 decal->color4f[0][1] = c0[1];
9215 decal->color4f[0][2] = c0[2];
9216 decal->color4f[0][3] = 1;
9217 decal->color4f[1][0] = c1[0];
9218 decal->color4f[1][1] = c1[1];
9219 decal->color4f[1][2] = c1[2];
9220 decal->color4f[1][3] = 1;
9221 decal->color4f[2][0] = c2[0];
9222 decal->color4f[2][1] = c2[1];
9223 decal->color4f[2][2] = c2[2];
9224 decal->color4f[2][3] = 1;
9225 decal->vertex3f[0][0] = v0[0];
9226 decal->vertex3f[0][1] = v0[1];
9227 decal->vertex3f[0][2] = v0[2];
9228 decal->vertex3f[1][0] = v1[0];
9229 decal->vertex3f[1][1] = v1[1];
9230 decal->vertex3f[1][2] = v1[2];
9231 decal->vertex3f[2][0] = v2[0];
9232 decal->vertex3f[2][1] = v2[1];
9233 decal->vertex3f[2][2] = v2[2];
9234 decal->texcoord2f[0][0] = t0[0];
9235 decal->texcoord2f[0][1] = t0[1];
9236 decal->texcoord2f[1][0] = t1[0];
9237 decal->texcoord2f[1][1] = t1[1];
9238 decal->texcoord2f[2][0] = t2[0];
9239 decal->texcoord2f[2][1] = t2[1];
9240 TriangleNormal(v0, v1, v2, decal->plane);
9241 VectorNormalize(decal->plane);
9242 decal->plane[3] = DotProduct(v0, decal->plane);
9243}
9244
9245extern cvar_t cl_decals_bias;
9248// baseparms, parms, temps
9249static void R_DecalSystem_SplatTriangle(decalsystem_t *decalsystem, float r, float g, float b, float a, float s1, float t1, float s2, float t2, unsigned int decalsequence, qbool dynamic, float (*planes)[4], matrix4x4_t *projection, int triangleindex, int surfaceindex)
9250{
9251 int cornerindex;
9252 int index;
9253 float v[9][3];
9254 const float *vertex3f;
9255 const float *normal3f;
9256 int numpoints;
9257 float points[2][9][3];
9258 float temp[3];
9259 float tc[9][2];
9260 float f;
9261 float c[9][4];
9262 const int *e;
9263
9264 e = rsurface.modelelement3i + 3*triangleindex;
9265
9266 vertex3f = rsurface.modelvertex3f;
9267 normal3f = rsurface.modelnormal3f;
9268
9269 if (normal3f)
9270 {
9271 for (cornerindex = 0;cornerindex < 3;cornerindex++)
9272 {
9273 index = 3*e[cornerindex];
9274 VectorMA(vertex3f + index, cl_decals_bias.value, normal3f + index, v[cornerindex]);
9275 }
9276 }
9277 else
9278 {
9279 for (cornerindex = 0;cornerindex < 3;cornerindex++)
9280 {
9281 index = 3*e[cornerindex];
9282 VectorCopy(vertex3f + index, v[cornerindex]);
9283 }
9284 }
9285
9286 // cull backfaces
9287 //TriangleNormal(v[0], v[1], v[2], normal);
9288 //if (DotProduct(normal, localnormal) < 0.0f)
9289 // continue;
9290 // clip by each of the box planes formed from the projection matrix
9291 // if anything survives, we emit the decal
9292 numpoints = PolygonF_Clip(3 , v[0] , planes[0][0], planes[0][1], planes[0][2], planes[0][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), points[1][0]);
9293 if (numpoints < 3)
9294 return;
9295 numpoints = PolygonF_Clip(numpoints, points[1][0], planes[1][0], planes[1][1], planes[1][2], planes[1][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), points[0][0]);
9296 if (numpoints < 3)
9297 return;
9298 numpoints = PolygonF_Clip(numpoints, points[0][0], planes[2][0], planes[2][1], planes[2][2], planes[2][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), points[1][0]);
9299 if (numpoints < 3)
9300 return;
9301 numpoints = PolygonF_Clip(numpoints, points[1][0], planes[3][0], planes[3][1], planes[3][2], planes[3][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), points[0][0]);
9302 if (numpoints < 3)
9303 return;
9304 numpoints = PolygonF_Clip(numpoints, points[0][0], planes[4][0], planes[4][1], planes[4][2], planes[4][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), points[1][0]);
9305 if (numpoints < 3)
9306 return;
9307 numpoints = PolygonF_Clip(numpoints, points[1][0], planes[5][0], planes[5][1], planes[5][2], planes[5][3], 1.0f/64.0f, sizeof(points[0])/sizeof(points[0][0]), v[0]);
9308 if (numpoints < 3)
9309 return;
9310 // some part of the triangle survived, so we have to accept it...
9311 if (dynamic)
9312 {
9313 // dynamic always uses the original triangle
9314 numpoints = 3;
9315 for (cornerindex = 0;cornerindex < 3;cornerindex++)
9316 {
9317 index = 3*e[cornerindex];
9318 VectorCopy(vertex3f + index, v[cornerindex]);
9319 }
9320 }
9321 for (cornerindex = 0;cornerindex < numpoints;cornerindex++)
9322 {
9323 // convert vertex positions to texcoords
9325 tc[cornerindex][0] = (temp[1]+1.0f)*0.5f * (s2-s1) + s1;
9326 tc[cornerindex][1] = (temp[2]+1.0f)*0.5f * (t2-t1) + t1;
9327 // calculate distance fade from the projection origin
9329 f = bound(0.0f, f, 1.0f);
9330 c[cornerindex][0] = r * f;
9331 c[cornerindex][1] = g * f;
9332 c[cornerindex][2] = b * f;
9333 c[cornerindex][3] = 1.0f;
9334 //VectorMA(v[cornerindex], cl_decals_bias.value, localnormal, v[cornerindex]);
9335 }
9336 if (dynamic)
9337 R_DecalSystem_SpawnTriangle(decalsystem, v[0], v[1], v[2], tc[0], tc[1], tc[2], c[0], c[1], c[2], triangleindex, surfaceindex, decalsequence);
9338 else
9339 for (cornerindex = 0;cornerindex < numpoints-2;cornerindex++)
9340 R_DecalSystem_SpawnTriangle(decalsystem, v[0], v[cornerindex+1], v[cornerindex+2], tc[0], tc[cornerindex+1], tc[cornerindex+2], c[0], c[cornerindex+1], c[cornerindex+2], -1, surfaceindex, decalsequence);
9341}
9342static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize, unsigned int decalsequence)
9343{
9345 decalsystem_t *decalsystem;
9346 qbool dynamic;
9347 model_t *model;
9348 const msurface_t *surface;
9349 const msurface_t *surfaces;
9350 const texture_t *texture;
9351 int numtriangles;
9352 int surfaceindex;
9353 int triangleindex;
9354 float localorigin[3];
9355 float localnormal[3];
9356 float localmins[3];
9357 float localmaxs[3];
9358 float localsize;
9359 //float normal[3];
9360 float planes[6][4];
9361 float angles[3];
9362 bih_t *bih;
9364 int bih_triangles[256];
9365 int bih_surfaces[256];
9366
9367 decalsystem = &ent->decalsystem;
9368 model = ent->model;
9369 if (!model || !ent->allowdecals || ent->alpha < 1 || (ent->flags & (RENDER_ADDITIVE | RENDER_NODEPTHTEST)))
9370 {
9372 return;
9373 }
9374
9375 if (!model->brush.data_leafs && !cl_decals_models.integer)
9376 {
9377 if (decalsystem->model)
9378 R_DecalSystem_Reset(decalsystem);
9379 return;
9380 }
9381
9382 if (decalsystem->model != model)
9383 R_DecalSystem_Reset(decalsystem);
9384 decalsystem->model = model;
9385
9386 RSurf_ActiveModelEntity(ent, true, false, false);
9387
9398
9399 //VectorCopy(localnormal, planes[4]);
9400 //VectorVectors(planes[4], planes[2], planes[0]);
9401 AnglesFromVectors(angles, localnormal, NULL, false);
9402 AngleVectors(angles, planes[0], planes[2], planes[4]);
9403 VectorNegate(planes[0], planes[1]);
9404 VectorNegate(planes[2], planes[3]);
9405 VectorNegate(planes[4], planes[5]);
9406 planes[0][3] = DotProduct(planes[0], localorigin) - localsize;
9407 planes[1][3] = DotProduct(planes[1], localorigin) - localsize;
9408 planes[2][3] = DotProduct(planes[2], localorigin) - localsize;
9409 planes[3][3] = DotProduct(planes[3], localorigin) - localsize;
9410 planes[4][3] = DotProduct(planes[4], localorigin) - localsize;
9411 planes[5][3] = DotProduct(planes[5], localorigin) - localsize;
9412
9413#if 1
9414// works
9415{
9417 Matrix4x4_CreateFromQuakeEntity(&forwardprojection, localorigin[0], localorigin[1], localorigin[2], angles[0], angles[1], angles[2], localsize);
9419}
9420#else
9421// broken
9422{
9423 float projectionvector[4][3];
9424 VectorScale(planes[0], ilocalsize, projectionvector[0]);
9425 VectorScale(planes[2], ilocalsize, projectionvector[1]);
9426 VectorScale(planes[4], ilocalsize, projectionvector[2]);
9427 projectionvector[0][0] = planes[0][0] * ilocalsize;
9428 projectionvector[0][1] = planes[1][0] * ilocalsize;
9429 projectionvector[0][2] = planes[2][0] * ilocalsize;
9430 projectionvector[1][0] = planes[0][1] * ilocalsize;
9431 projectionvector[1][1] = planes[1][1] * ilocalsize;
9432 projectionvector[1][2] = planes[2][1] * ilocalsize;
9433 projectionvector[2][0] = planes[0][2] * ilocalsize;
9434 projectionvector[2][1] = planes[1][2] * ilocalsize;
9435 projectionvector[2][2] = planes[2][2] * ilocalsize;
9440}
9441#endif
9442
9443 dynamic = model->surfmesh.isanimated;
9444 surfaces = model->data_surfaces;
9445
9446 bih = NULL;
9448 if(!dynamic)
9449 {
9450 if(model->render_bih.numleafs)
9451 bih = &model->render_bih;
9452 else if(model->collision_bih.numleafs)
9453 bih = &model->collision_bih;
9454 }
9455 if(bih)
9457 if(bih_triangles_count == 0)
9458 return;
9459 if(bih_triangles_count > (int) (sizeof(bih_triangles) / sizeof(*bih_triangles))) // hit too many, likely bad anyway
9460 return;
9461 if(bih_triangles_count > 0)
9462 {
9463 for (triangleindex = 0; triangleindex < bih_triangles_count; ++triangleindex)
9464 {
9465 surfaceindex = bih_surfaces[triangleindex];
9466 surface = surfaces + surfaceindex;
9467 texture = surface->texture;
9468 if (!texture)
9469 continue;
9471 continue;
9472 if (texture->surfaceflags & Q3SURFACEFLAG_NOMARKS)
9473 continue;
9474 R_DecalSystem_SplatTriangle(decalsystem, r, g, b, a, s1, t1, s2, t2, decalsequence, dynamic, planes, &projection, bih_triangles[triangleindex], surfaceindex);
9475 }
9476 }
9477 else
9478 {
9479 for (surfaceindex = model->submodelsurfaces_start;surfaceindex < model->submodelsurfaces_end;surfaceindex++)
9480 {
9481 surface = surfaces + surfaceindex;
9482 // check cull box first because it rejects more than any other check
9483 if (!dynamic && !BoxesOverlap(surface->mins, surface->maxs, localmins, localmaxs))
9484 continue;
9485 // skip transparent surfaces
9486 texture = surface->texture;
9487 if (!texture)
9488 continue;
9490 continue;
9491 if (texture->surfaceflags & Q3SURFACEFLAG_NOMARKS)
9492 continue;
9493 numtriangles = surface->num_triangles;
9494 for (triangleindex = 0; triangleindex < numtriangles; triangleindex++)
9495 R_DecalSystem_SplatTriangle(decalsystem, r, g, b, a, s1, t1, s2, t2, decalsequence, dynamic, planes, &projection, triangleindex + surface->num_firsttriangle, surfaceindex);
9496 }
9497 }
9498}
9499
9500// do not call this outside of rendering code - use R_DecalSystem_SplatEntities instead
9501static void R_DecalSystem_ApplySplatEntities(const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize, unsigned int decalsequence)
9502{
9504 float worldmins[3];
9505 float worldmaxs[3];
9506 entity_render_t *ent;
9507
9508 worldmins[0] = worldorigin[0] - worldsize;
9509 worldmins[1] = worldorigin[1] - worldsize;
9510 worldmins[2] = worldorigin[2] - worldsize;
9511 worldmaxs[0] = worldorigin[0] + worldsize;
9512 worldmaxs[1] = worldorigin[1] + worldsize;
9513 worldmaxs[2] = worldorigin[2] + worldsize;
9514
9515 R_DecalSystem_SplatEntity(r_refdef.scene.worldentity, worldorigin, worldnormal, r, g, b, a, s1, t1, s2, t2, worldsize, decalsequence);
9516
9518 {
9520 if (!BoxesOverlap(ent->mins, ent->maxs, worldmins, worldmaxs))
9521 continue;
9522
9523 R_DecalSystem_SplatEntity(ent, worldorigin, worldnormal, r, g, b, a, s1, t1, s2, t2, worldsize, decalsequence);
9524 }
9525}
9526
9528{
9531 float color[4];
9532 float tcrange[4];
9534 unsigned int decalsequence;
9535}
9537
9540
9541void R_DecalSystem_SplatEntities(const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize)
9542{
9544
9546 return;
9547
9549 VectorCopy(worldorigin, queue->worldorigin);
9550 VectorCopy(worldnormal, queue->worldnormal);
9551 Vector4Set(queue->color, r, g, b, a);
9552 Vector4Set(queue->tcrange, s1, t1, s2, t2);
9553 queue->worldsize = worldsize;
9554 queue->decalsequence = cl.decalsequence++;
9555}
9556
9558{
9559 int i;
9561
9562 for (i = 0, queue = r_decalsystem_queue;i < r_decalsystem_numqueued;i++, queue++)
9563 R_DecalSystem_ApplySplatEntities(queue->worldorigin, queue->worldnormal, queue->color[0], queue->color[1], queue->color[2], queue->color[3], queue->tcrange[0], queue->tcrange[1], queue->tcrange[2], queue->tcrange[3], queue->worldsize, queue->decalsequence);
9565}
9566
9567extern cvar_t cl_decals_max;
9569{
9570 int i;
9571 decalsystem_t *decalsystem = &ent->decalsystem;
9572 int numdecals;
9573 unsigned int killsequence;
9575 float frametime;
9576 float lifetime;
9577
9578 if (!decalsystem->numdecals)
9579 return;
9580
9582 return;
9583
9584 if (ent->model != decalsystem->model || ent->alpha < 1 || (ent->flags & RENDER_ADDITIVE))
9585 {
9586 R_DecalSystem_Reset(decalsystem);
9587 return;
9588 }
9589
9592
9593 if (decalsystem->lastupdatetime)
9594 frametime = (r_refdef.scene.time - decalsystem->lastupdatetime);
9595 else
9596 frametime = 0;
9597 decalsystem->lastupdatetime = r_refdef.scene.time;
9598 numdecals = decalsystem->numdecals;
9599
9600 for (i = 0, decal = decalsystem->decals;i < numdecals;i++, decal++)
9601 {
9602 if (decal->color4f[0][3])
9603 {
9604 decal->lived += frametime;
9605 if (killsequence > decal->decalsequence || decal->lived >= lifetime)
9606 {
9607 memset(decal, 0, sizeof(*decal));
9608 if (decalsystem->freedecal > i)
9609 decalsystem->freedecal = i;
9610 }
9611 }
9612 }
9613 decal = decalsystem->decals;
9614 while (numdecals > 0 && !decal[numdecals-1].color4f[0][3])
9615 numdecals--;
9616
9617 // collapse the array by shuffling the tail decals into the gaps
9618 for (;;)
9619 {
9620 while (decalsystem->freedecal < numdecals && decal[decalsystem->freedecal].color4f[0][3])
9621 decalsystem->freedecal++;
9622 if (decalsystem->freedecal == numdecals)
9623 break;
9624 decal[decalsystem->freedecal] = decal[--numdecals];
9625 }
9626
9627 decalsystem->numdecals = numdecals;
9628
9629 if (numdecals <= 0)
9630 {
9631 // if there are no decals left, reset decalsystem
9632 R_DecalSystem_Reset(decalsystem);
9633 }
9634}
9635
9638{
9639 int i;
9640 decalsystem_t *decalsystem = &ent->decalsystem;
9641 int numdecals;
9643 float faderate;
9644 float alpha;
9645 float *v3f;
9646 float *c4f;
9647 float *t2f;
9648 const int *e;
9650 int numtris = 0;
9651
9652 numdecals = decalsystem->numdecals;
9653 if (!numdecals)
9654 return;
9655
9657 return;
9658
9659 if (ent->model != decalsystem->model || ent->alpha < 1 || (ent->flags & RENDER_ADDITIVE))
9660 {
9661 R_DecalSystem_Reset(decalsystem);
9662 return;
9663 }
9664
9665 // if the model is static it doesn't matter what value we give for
9666 // wantnormals and wanttangents, so this logic uses only rules applicable
9667 // to a model, knowing that they are meaningless otherwise
9668 RSurf_ActiveModelEntity(ent, false, false, false);
9669
9670 decalsystem->lastupdatetime = r_refdef.scene.time;
9671
9672 faderate = 1.0f / max(0.001f, cl_decals_fadetime.value);
9673
9674 // update vertex positions for animated models
9675 v3f = decalsystem->vertex3f;
9676 c4f = decalsystem->color4f;
9677 t2f = decalsystem->texcoord2f;
9678 for (i = 0, decal = decalsystem->decals;i < numdecals;i++, decal++)
9679 {
9680 if (!decal->color4f[0][3])
9681 continue;
9682
9683 if (surfacevisible && !surfacevisible[decal->surfaceindex])
9684 continue;
9685
9686 // skip backfaces
9687 if (decal->triangleindex < 0 && DotProduct(r_refdef.view.origin, decal->plane) < decal->plane[3])
9688 continue;
9689
9690 // update color values for fading decals
9691 if (decal->lived >= cl_decals_time.value)
9692 alpha = 1 - faderate * (decal->lived - cl_decals_time.value);
9693 else
9694 alpha = 1.0f;
9695
9696 c4f[ 0] = decal->color4f[0][0] * alpha;
9697 c4f[ 1] = decal->color4f[0][1] * alpha;
9698 c4f[ 2] = decal->color4f[0][2] * alpha;
9699 c4f[ 3] = 1;
9700 c4f[ 4] = decal->color4f[1][0] * alpha;
9701 c4f[ 5] = decal->color4f[1][1] * alpha;
9702 c4f[ 6] = decal->color4f[1][2] * alpha;
9703 c4f[ 7] = 1;
9704 c4f[ 8] = decal->color4f[2][0] * alpha;
9705 c4f[ 9] = decal->color4f[2][1] * alpha;
9706 c4f[10] = decal->color4f[2][2] * alpha;
9707 c4f[11] = 1;
9708
9709 t2f[0] = decal->texcoord2f[0][0];
9710 t2f[1] = decal->texcoord2f[0][1];
9711 t2f[2] = decal->texcoord2f[1][0];
9712 t2f[3] = decal->texcoord2f[1][1];
9713 t2f[4] = decal->texcoord2f[2][0];
9714 t2f[5] = decal->texcoord2f[2][1];
9715
9716 // update vertex positions for animated models
9717 if (decal->triangleindex >= 0 && decal->triangleindex < rsurface.modelnumtriangles)
9718 {
9719 e = rsurface.modelelement3i + 3*decal->triangleindex;
9721 VectorCopy(rsurface.modelvertex3f + 3*e[1], v3f + 3);
9722 VectorCopy(rsurface.modelvertex3f + 3*e[2], v3f + 6);
9723 }
9724 else
9725 {
9726 VectorCopy(decal->vertex3f[0], v3f);
9727 VectorCopy(decal->vertex3f[1], v3f + 3);
9728 VectorCopy(decal->vertex3f[2], v3f + 6);
9729 }
9730
9731 if (r_refdef.fogenabled)
9732 {
9735 alpha = RSurf_FogVertex(v3f + 3);
9736 VectorScale(c4f + 4, alpha, c4f + 4);
9737 alpha = RSurf_FogVertex(v3f + 6);
9738 VectorScale(c4f + 8, alpha, c4f + 8);
9739 }
9740
9741 v3f += 9;
9742 c4f += 12;
9743 t2f += 6;
9744 numtris++;
9745 }
9746
9747 if (numtris > 0)
9748 {
9749 r_refdef.stats[r_stat_drawndecals] += numtris;
9750
9751 // now render the decals all at once
9752 // (this assumes they all use one particle font texture!)
9753 RSurf_ActiveCustomEntity(&rsurface.matrix, &rsurface.inversematrix, rsurface.ent_flags, ent->shadertime, 1, 1, 1, 1, numdecals*3, decalsystem->vertex3f, decalsystem->texcoord2f, NULL, NULL, NULL, decalsystem->color4f, numtris, decalsystem->element3i, decalsystem->element3s, false, false);
9754// R_Mesh_ResetTextureState();
9755 R_Mesh_PrepareVertices_Generic_Arrays(numtris * 3, decalsystem->vertex3f, decalsystem->color4f, decalsystem->texcoord2f);
9756 GL_DepthMask(false);
9757 GL_DepthRange(0, 1);
9759 GL_DepthTest(true);
9762 R_SetupShader_Generic(decalskinframe->base, false, false, false);
9763 R_Mesh_Draw(0, numtris * 3, 0, numtris, decalsystem->element3i, NULL, 0, decalsystem->element3s, NULL, 0);
9764 }
9765}
9766
9767static void R_DrawModelDecals(void)
9768{
9769 int i, numdecals;
9770
9771 // fade faster when there are too many decals
9773 for (i = 0;i < r_refdef.scene.numentities;i++)
9775
9777 for (i = 0;i < r_refdef.scene.numentities;i++)
9780
9782
9784 for (i = 0;i < r_refdef.scene.numentities;i++)
9786
9787 r_refdef.stats[r_stat_totaldecals] += numdecals;
9788
9790 return;
9791
9793
9794 for (i = 0;i < r_refdef.scene.numentities;i++)
9795 {
9797 continue;
9800 }
9801}
9802
9803static void R_DrawDebugModel(void)
9804{
9806 int j, flagsmask;
9807 const msurface_t *surface;
9808 model_t *model = ent->model;
9809
9810 if (!sv.active && !cls.demoplayback && ent != r_refdef.scene.worldentity)
9811 return;
9812
9813 if (r_showoverdraw.value > 0)
9814 {
9815 float c = r_refdef.view.colorscale * r_showoverdraw.value * 0.125f;
9817 R_SetupShader_Generic_NoTexture(false, false);
9818 GL_DepthTest(false);
9819 GL_DepthMask(false);
9820 GL_DepthRange(0, 1);
9822 for (j = model->submodelsurfaces_start;j < model->submodelsurfaces_end;j++)
9823 {
9825 continue;
9826 surface = model->data_surfaces + j;
9828 if ((rsurface.texture->currentmaterialflags & flagsmask) && surface->num_triangles)
9829 {
9833 GL_Color(c, 0, 0, 1.0f);
9834 else if (ent == r_refdef.scene.worldentity)
9835 GL_Color(c, c, c, 1.0f);
9836 else
9837 GL_Color(0, c, 0, 1.0f);
9840 }
9841 }
9843 }
9844
9846
9847// R_Mesh_ResetTextureState();
9848 R_SetupShader_Generic_NoTexture(false, false);
9849 GL_DepthRange(0, 1);
9851 GL_DepthMask(false);
9853
9855 {
9856 int triangleindex;
9857 int bihleafindex;
9858 qbool cullbox = false;
9859 const q3mbrush_t *brush;
9860 const bih_t *bih = &model->collision_bih;
9861 const bih_leaf_t *bihleaf;
9862 float vertex3f[3][3];
9864 for (bihleafindex = 0, bihleaf = bih->leafs;bihleafindex < bih->numleafs;bihleafindex++, bihleaf++)
9865 {
9866 if (cullbox && R_CullFrustum(bihleaf->mins, bihleaf->maxs))
9867 continue;
9868 switch (bihleaf->type)
9869 {
9870 case BIH_BRUSH:
9871 brush = model->brush.data_brushes + bihleaf->itemindex;
9872 if (brush->colbrushf && brush->colbrushf->numtriangles)
9873 {
9874 GL_Color((bihleafindex & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((bihleafindex >> 5) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((bihleafindex >> 10) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, r_showcollisionbrushes.value);
9875 R_Mesh_PrepareVertices_Generic_Arrays(brush->colbrushf->numpoints, brush->colbrushf->points->v, NULL, NULL);
9876 R_Mesh_Draw(0, brush->colbrushf->numpoints, 0, brush->colbrushf->numtriangles, brush->colbrushf->elements, NULL, 0, NULL, NULL, 0);
9877 }
9878 break;
9880 triangleindex = bihleaf->itemindex;
9881 VectorCopy(model->brush.data_collisionvertex3f + 3*model->brush.data_collisionelement3i[triangleindex*3+0], vertex3f[0]);
9882 VectorCopy(model->brush.data_collisionvertex3f + 3*model->brush.data_collisionelement3i[triangleindex*3+1], vertex3f[1]);
9883 VectorCopy(model->brush.data_collisionvertex3f + 3*model->brush.data_collisionelement3i[triangleindex*3+2], vertex3f[2]);
9884 GL_Color((bihleafindex & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((bihleafindex >> 5) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((bihleafindex >> 10) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, r_showcollisionbrushes.value);
9887 break;
9888 case BIH_RENDERTRIANGLE:
9889 triangleindex = bihleaf->itemindex;
9890 VectorCopy(model->surfmesh.data_vertex3f + 3*model->surfmesh.data_element3i[triangleindex*3+0], vertex3f[0]);
9891 VectorCopy(model->surfmesh.data_vertex3f + 3*model->surfmesh.data_element3i[triangleindex*3+1], vertex3f[1]);
9892 VectorCopy(model->surfmesh.data_vertex3f + 3*model->surfmesh.data_element3i[triangleindex*3+2], vertex3f[2]);
9893 GL_Color((bihleafindex & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((bihleafindex >> 5) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((bihleafindex >> 10) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, r_showcollisionbrushes.value);
9896 break;
9897 }
9898 }
9899 }
9900
9902
9903#ifndef USE_GLES2
9904 if (r_showtris.value > 0 && qglPolygonMode)
9905 {
9907 {
9909 GL_DepthMask(false);
9910 }
9911 else
9912 {
9914 GL_DepthMask(true);
9915 }
9917 for (j = model->submodelsurfaces_start; j < model->submodelsurfaces_end; j++)
9918 {
9920 continue;
9921 surface = model->data_surfaces + j;
9923 if ((rsurface.texture->currentmaterialflags & flagsmask) && surface->num_triangles)
9924 {
9928 else if (ent == r_refdef.scene.worldentity)
9930 else
9934 }
9935 }
9938 }
9939
9940# if 0
9941 // FIXME! implement r_shownormals with just triangles
9942 if (r_shownormals.value != 0 && qglBegin)
9943 {
9944 int l, k;
9945 vec3_t v;
9947 {
9949 GL_DepthMask(false);
9950 }
9951 else
9952 {
9954 GL_DepthMask(true);
9955 }
9956 for (j = model->submodelsurfaces_start; j < model->submodelsurfaces_end; j++)
9957 {
9959 continue;
9960 surface = model->data_surfaces + j;
9962 if ((rsurface.texture->currentmaterialflags & flagsmask) && surface->num_triangles)
9963 {
9967 {
9969 {
9971 GL_Color(0, 0, r_refdef.view.colorscale, 1);
9972 qglVertex3f(v[0], v[1], v[2]);
9975 qglVertex3f(v[0], v[1], v[2]);
9976 }
9977 }
9979 {
9981 {
9983 GL_Color(r_refdef.view.colorscale, 0, 0, 1);
9984 qglVertex3f(v[0], v[1], v[2]);
9987 qglVertex3f(v[0], v[1], v[2]);
9988 }
9989 }
9991 {
9993 {
9995 GL_Color(0, r_refdef.view.colorscale, 0, 1);
9996 qglVertex3f(v[0], v[1], v[2]);
9999 qglVertex3f(v[0], v[1], v[2]);
10000 }
10001 }
10003 {
10005 {
10007 GL_Color(0, 0, r_refdef.view.colorscale, 1);
10008 qglVertex3f(v[0], v[1], v[2]);
10011 qglVertex3f(v[0], v[1], v[2]);
10012 }
10013 }
10014 qglEnd();
10016 }
10017 }
10019 }
10020# endif
10021#endif
10022}
10023
10027{
10028 int i, j, flagsmask;
10029 model_t *model = ent->model;
10031 unsigned char *update;
10032 int numsurfacelist = 0;
10033 if (model == NULL)
10034 return;
10035
10036 if (r_maxsurfacelist < model->num_surfaces)
10037 {
10039 if (r_surfacelist)
10042 }
10043
10045 RSurf_ActiveModelEntity(ent, false, false, false);
10046 else if (prepass)
10047 RSurf_ActiveModelEntity(ent, true, true, true);
10048 else if (depthonly)
10049 RSurf_ActiveModelEntity(ent, model->wantnormals, model->wanttangents, false);
10050 else
10051 RSurf_ActiveModelEntity(ent, true, true, false);
10052
10053 surfaces = model->data_surfaces;
10055
10057
10058 if (debug)
10059 {
10061 rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity
10062 return;
10063 }
10064
10065 // check if this is an empty model
10066 if (model->submodelsurfaces_start >= model->submodelsurfaces_end)
10067 return;
10068
10074 numsurfacelist = 0;
10075
10076 // add visible surfaces to draw list
10077 if (ent == r_refdef.scene.worldentity)
10078 {
10079 // for the world entity, check surfacevisible
10080 for (i = model->submodelsurfaces_start;i < model->submodelsurfaces_end;i++)
10081 {
10082 j = model->modelsurfaces_sorted[i];
10085 }
10086
10087 // don't do anything if there were no surfaces added (none of the world entity is visible)
10088 if (!numsurfacelist)
10089 {
10090 rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity
10091 return;
10092 }
10093 }
10094 else if (ui)
10095 {
10096 // for ui we have to preserve the order of surfaces (not using modelsurfaces_sorted)
10097 for (i = model->submodelsurfaces_start; i < model->submodelsurfaces_end; i++)
10099 }
10100 else
10101 {
10102 // add all surfaces
10103 for (i = model->submodelsurfaces_start; i < model->submodelsurfaces_end; i++)
10105 }
10106
10107 /*
10108 * Mark lightmaps as dirty if their lightstyle's value changed. We do this by
10109 * using style chains because most styles do not change on most frames, and most
10110 * surfaces do not have styles on them. Mods like Arcane Dimensions (e.g. ad_necrokeep)
10111 * break this rule and animate most surfaces.
10112 */
10114 {
10116
10117 // For each lightstyle, check if its value changed and mark the lightmaps as dirty if so
10118 for (i = 0, style = model->brushq1.data_lightstyleinfo; i < model->brushq1.num_lightstyles; i++, style++)
10119 {
10120 if (style->value != r_refdef.scene.lightstylevalue[style->style])
10121 {
10122 int* list = style->surfacelist;
10123 style->value = r_refdef.scene.lightstylevalue[style->style];
10124 // Value changed - mark the surfaces belonging to this style chain as dirty
10125 for (j = 0; j < style->numsurfaces; j++)
10126 update[list[j]] = true;
10127 }
10128 }
10129 // Now check if update flags are set on any surfaces that are visible
10131 {
10132 /*
10133 * We can do less frequent texture uploads (approximately 10hz for animated
10134 * lightstyles) by rebuilding lightmaps on surfaces that are not currently visible.
10135 * For optimal efficiency, this includes the submodels of the worldmodel, so we
10136 * use model->num_surfaces, not nummodelsurfaces.
10137 */
10138 for (i = 0; i < model->num_surfaces;i++)
10139 if (update[i])
10141 }
10142 else
10143 {
10144 for (i = 0; i < numsurfacelist; i++)
10147 }
10148 }
10149
10151
10152 // add to stats if desired
10154 {
10156 for (j = 0;j < numsurfacelist;j++)
10158 }
10159
10160 rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveModelEntity
10161}
10162
10163void R_DebugLine(vec3_t start, vec3_t end)
10164{
10165 model_t *mod = CL_Mesh_UI();
10167 int e0, e1, e2, e3;
10168 float offsetx, offsety, x1, y1, x2, y2, width = 1.0f;
10169 float r1 = 1.0f, g1 = 0.0f, b1 = 0.0f, alpha1 = 0.25f;
10170 float r2 = 1.0f, g2 = 1.0f, b2 = 0.0f, alpha2 = 0.25f;
10171 vec4_t w[2], s[2];
10172
10173 // transform to screen coords first
10174 Vector4Set(w[0], start[0], start[1], start[2], 1);
10175 Vector4Set(w[1], end[0], end[1], end[2], 1);
10178 x1 = s[0][0] * vid_conwidth.value / vid.mode.width;
10179 y1 = (vid.mode.height - s[0][1]) * vid_conheight.value / vid.mode.height;
10180 x2 = s[1][0] * vid_conwidth.value / vid.mode.width;
10181 y2 = (vid.mode.height - s[1][1]) * vid_conheight.value / vid.mode.height;
10182 //Con_DPrintf("R_DebugLine: %.0f,%.0f to %.0f,%.0f\n", x1, y1, x2, y2);
10183
10184 // add the line to the UI mesh for drawing later
10185
10186 // width is measured in real pixels
10187 if (fabs(x2 - x1) > fabs(y2 - y1))
10188 {
10189 offsetx = 0;
10191 }
10192 else
10193 {
10195 offsety = 0;
10196 }
10198 e0 = Mod_Mesh_IndexForVertex(mod, surf, x1 - offsetx, y1 - offsety, 10, 0, 0, -1, 0, 0, 0, 0, r1, g1, b1, alpha1);
10199 e1 = Mod_Mesh_IndexForVertex(mod, surf, x2 - offsetx, y2 - offsety, 10, 0, 0, -1, 0, 0, 0, 0, r2, g2, b2, alpha2);
10200 e2 = Mod_Mesh_IndexForVertex(mod, surf, x2 + offsetx, y2 + offsety, 10, 0, 0, -1, 0, 0, 0, 0, r2, g2, b2, alpha2);
10201 e3 = Mod_Mesh_IndexForVertex(mod, surf, x1 + offsetx, y1 + offsety, 10, 0, 0, -1, 0, 0, 0, 0, r1, g1, b1, alpha1);
10202 Mod_Mesh_AddTriangle(mod, surf, e0, e1, e2);
10203 Mod_Mesh_AddTriangle(mod, surf, e0, e2, e3);
10204
10205}
10206
10207
10208void R_DrawCustomSurface(skinframe_t *skinframe, const matrix4x4_t *texmatrix, int materialflags, int firstvertex, int numvertices, int firsttriangle, int numtriangles, qbool writedepth, qbool prepass, qbool ui)
10209{
10210 static texture_t texture;
10211
10212 // fake enough texture and surface state to render this geometry
10213
10214 texture.update_lastrenderframe = -1; // regenerate this texture
10215 texture.basematerialflags = materialflags | MATERIALFLAG_CUSTOMSURFACE | MATERIALFLAG_WALL;
10216 texture.basealpha = 1.0f;
10217 texture.currentskinframe = skinframe;
10218 texture.currenttexmatrix = *texmatrix; // requires MATERIALFLAG_CUSTOMSURFACE
10219 texture.offsetmapping = OFFSETMAPPING_OFF;
10220 texture.offsetscale = 1;
10221 texture.specularscalemod = 1;
10222 texture.specularpowermod = 1;
10223 texture.transparentsort = TRANSPARENTSORT_DISTANCE;
10224
10225 R_DrawCustomSurface_Texture(&texture, texmatrix, materialflags, firstvertex, numvertices, firsttriangle, numtriangles, writedepth, prepass, ui);
10226}
10227
10228void R_DrawCustomSurface_Texture(texture_t *texture, const matrix4x4_t *texmatrix, int materialflags, int firstvertex, int numvertices, int firsttriangle, int numtriangles, qbool writedepth, qbool prepass, qbool ui)
10229{
10230 static msurface_t surface;
10231 const msurface_t *surfacelist = &surface;
10232
10233 // fake enough texture and surface state to render this geometry
10235 surface.num_triangles = numtriangles;
10236 surface.num_firsttriangle = firsttriangle;
10237 surface.num_vertices = numvertices;
10238 surface.num_firstvertex = firstvertex;
10239
10240 // now render it
10246}
int BIH_GetTriangleListForBox(const bih_t *bih, int maxtriangles, int *trianglelist_idx, int *trianglelist_surf, const float *mins, const float *maxs)
Definition bih.c:211
@ BIH_COLLISIONTRIANGLE
Definition bih.h:30
@ BIH_RENDERTRIANGLE
Definition bih.h:31
@ BIH_BRUSH
Definition bih.h:29
#define SUPERCONTENTS_SKY
Definition bspfile.h:200
#define SUPERCONTENTS_SOLID
Definition bspfile.h:196
trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, float extend, qbool hitnetworkbrushmodels, qbool hitnetworkplayers, int *hitnetworkentity, qbool hitcsqcentities, qbool hitsurfaces)
trace_t CL_Cache_TraceLineSurfaces(const vec3_t start, const vec3_t end, int type, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask)
static vec3_t offsets[NUMOFFSETS]
Definition cl_input.c:838
cl_locnode_t * CL_Locs_FindNearest(const vec3_t point)
Definition cl_main.c:2200
client_state_t cl
Definition cl_main.c:117
client_static_t cls
Definition cl_main.c:116
void CL_MeshEntities_Init(void)
Definition cl_main.c:2559
entity_t cl_meshentities[NUM_MESHENTITIES]
Definition cl_main.c:2517
void CL_ParseEntityLump(char *entdata)
Definition cl_parse.c:384
void R_DrawParticles(void)
cvar_t cl_decals_fadetime
void R_Particles_Init(void)
cvar_t cl_decals_time
int r_stereo_side
Definition cl_screen.c:1584
cvar_t r_stereo_angle
Definition cl_screen.c:87
qbool R_Stereo_ColorMasking(void)
Definition cl_screen.c:2103
void R_ClearScreen(qbool fogcolor)
Definition cl_screen.c:1565
qbool R_Stereo_Active(void)
Definition cl_screen.c:2108
cvar_t r_stereo_separation
Definition cl_screen.c:80
cvar_t vid_conheight
Definition cl_screen.c:57
cvar_t vid_conwidth
Definition cl_screen.c:56
int cl_videoplaying
Definition cl_video.c:458
#define CL_Mesh_UI()
Definition client.h:1373
@ MESH_UI
Definition client.h:1366
@ ca_dedicated
Definition client.h:531
#define CSHIFT_DAMAGE
Definition client.h:513
void Cmd_AddCommand(unsigned flags, const char *cmd_name, xcommand_t function, const char *description)
called by the init functions of other parts of the program to register commands and functions to call...
Definition cmd.c:1643
cmd_state_t * cmd_local
command interpreter for local commands injected by SVQC, CSQC, MQC, server or client engine code uses...
Definition cmd.c:25
#define CF_CLIENT
cvar/command that only the client can change/execute
Definition cmd.h:48
#define CF_ARCHIVE
cvar should have its set value saved to config.cfg and persist across sessions
Definition cmd.h:53
void Collision_Cache_Reset(qbool resetlimits)
Definition collision.c:1480
unsigned short CRC_Block(const unsigned char *data, size_t size)
Definition com_crc16.c:75
gamemode_t gamemode
Definition com_game.c:26
@ GAME_NEHAHRA
Definition com_game.h:32
@ GAME_TENEBRAE
Definition com_game.h:41
char * va(char *buf, size_t buflen, const char *format,...)
Definition common.c:972
int dpsnprintf(char *buffer, size_t buffersize, const char *format,...)
Returns the number of printed characters, excluding the final '\0' or returns -1 if the buffer isn't ...
Definition common.c:997
@ PROTOCOL_QUAKEWORLD
quakeworld protocol
Definition common.h:145
#define dp_strlcat(dst, src, dsize)
Definition common.h:304
#define dp_strlcpy(dst, src, dsize)
Definition common.h:303
void Con_Print(const char *msg)
Prints to all appropriate console targets, and adds timestamps.
Definition console.c:1450
void Con_DPrintf(const char *fmt,...)
A Con_Printf that only shows up if the "developer" cvar is set.
Definition console.c:1490
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
Definition console.c:1460
#define CON_ERROR
Definition console.h:97
qbool CL_VM_TransformView(int entnum, matrix4x4_t *viewmatrix, mplane_t *clipplane, vec3_t visorigin)
Definition csprogs.c:1196
void Cvar_SetValueQuick(cvar_t *var, float value)
Definition cvar.c:473
cvar_state_t cvars_all
Definition cvar.c:28
void Cvar_SetValue(cvar_state_t *cvars, const char *var_name, float value)
expands value to a string and calls Cvar_Set
Definition cvar.c:484
void Cvar_Set(cvar_state_t *cvars, const char *var_name, const char *value)
equivelant to "<name> <variable>" typed at the console
Definition cvar.c:456
void Cvar_RegisterVariable(cvar_t *variable)
registers a cvar that already has the name, string, and optionally the archive elements set.
Definition cvar.c:599
void DrawQ_Start(void)
Definition gl_draw.c:788
void DrawQ_Finish(void)
Definition gl_draw.c:1454
float noise4f(float x, float y, float z, float w)
#define n(x, y)
unsigned char * FS_LoadFile(const char *path, mempool_t *pool, qbool quiet, fs_offset_t *filesizepointer)
Definition fs.c:3536
qfile_t * FS_OpenRealFile(const char *filepath, const char *mode, qbool quiet)
Definition fs.c:2897
static int(ZEXPORT *qz_inflate)(z_stream *strm
int FS_Close(qfile_t *file)
Definition fs.c:2966
int FS_Print(qfile_t *file, const char *msg)
Definition fs.c:3257
int64_t fs_offset_t
Definition fs.h:37
void Font_Init(void)
Definition ft2.c:443
void R_Mesh_PrepareVertices_Vertex3f(int numvertices, const float *vertex3f, const r_meshbuffer_t *vertexbuffer, int bufferoffset)
float gl_modelviewprojection16f[16]
Definition gl_backend.c:26
matrix4x4_t gl_modelmatrix
Definition gl_backend.c:20
void GL_Clear(int mask, const float *colorvalue, float depthvalue, int stencilvalue)
void R_Mesh_VertexPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
void R_Mesh_CopyToTexture(rtexture_t *tex, int tx, int ty, int sx, int sy, int width, int height)
cvar_t r_renderview
Definition gl_backend.c:12
void GL_CullFace(int state)
void GL_ColorMask(int r, int g, int b, int a)
unsigned short polygonelement3s[(POLYGONELEMENTS_MAXPOINTS-2) *3]
Definition gl_backend.c:242
void R_Mesh_TexCoordPointer(unsigned int unitnum, int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
void GL_DepthMask(int state)
void GL_Backend_FreeProgram(unsigned int prog)
matrix4x4_t gl_modelviewprojectionmatrix
Definition gl_backend.c:24
int polygonelement3i[(POLYGONELEMENTS_MAXPOINTS-2) *3]
Definition gl_backend.c:241
void R_Mesh_TexBind(unsigned int unitnum, rtexture_t *tex)
void R_Mesh_ColorPointer(int components, int gltype, size_t stride, const void *pointer, const r_meshbuffer_t *vertexbuffer, size_t bufferoffset)
void GL_DepthFunc(int state)
void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const r_meshbuffer_t *element3i_indexbuffer, int element3i_bufferoffset, const unsigned short *element3s, const r_meshbuffer_t *element3s_indexbuffer, int element3s_bufferoffset)
void R_Viewport_TransformToScreen(const r_viewport_t *v, const vec4_t in, vec4_t out)
Definition gl_backend.c:382
void R_Viewport_InitPerspective(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float frustumx, float frustumy, float nearclip, float farclip, const float *nearplane)
Definition gl_backend.c:676
void GL_DepthTest(int state)
void GL_DepthRange(float nearfrac, float farfrac)
void R_Viewport_InitOrtho3D(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float frustumx, float frustumy, float nearclip, float farclip, const float *nearplane)
Definition gl_backend.c:634
void GL_PolygonOffset(float planeoffset, float depthoffset)
r_meshbuffer_t * R_Mesh_CreateMeshBuffer(const void *data, size_t size, const char *name, qbool isindexbuffer, qbool isuniformbuffer, qbool isdynamic, qbool isindex16)
int R_Mesh_CreateFramebufferObject(rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4)
Definition gl_backend.c:959
void R_SetViewport(const r_viewport_t *v)
Definition gl_backend.c:896
void R_Viewport_InitOrtho(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float x1, float y1, float x2, float y2, float nearclip, float farclip, const float *nearplane)
Definition gl_backend.c:586
matrix4x4_t gl_modelviewmatrix
Definition gl_backend.c:22
void R_Mesh_DestroyMeshBuffer(r_meshbuffer_t *buffer)
void R_Mesh_ResetTextureState(void)
matrix4x4_t gl_projectionmatrix
Definition gl_backend.c:23
void GL_Color(float cr, float cg, float cb, float ca)
void R_Mesh_SetRenderTargets(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4)
void R_Mesh_PrepareVertices_Mesh_Arrays(int numvertices, const float *vertex3f, const float *svector3f, const float *tvector3f, const float *normal3f, const float *color4f, const float *texcoordtexture2f, const float *texcoordlightmap2f)
void GL_BlendFunc(int blendfunc1, int blendfunc2)
qbool R_ScissorForBBox(const float *mins, const float *maxs, int *scissor)
Definition gl_backend.c:429
void R_Viewport_InitPerspectiveInfinite(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float frustumx, float frustumy, float nearclip, const float *nearplane)
Definition gl_backend.c:718
void GL_AlphaToCoverage(qbool state)
void GL_Scissor(int x, int y, int width, int height)
float gl_modelview16f[16]
Definition gl_backend.c:25
void R_Mesh_PrepareVertices_Generic_Arrays(int numvertices, const float *vertex3f, const float *color4f, const float *texcoord2f)
qbool gl_modelmatrixchanged
Definition gl_backend.c:27
void R_Mesh_UpdateMeshBuffer(r_meshbuffer_t *buffer, const void *data, size_t size, qbool subdata, size_t offset)
matrix4x4_t gl_viewmatrix
Definition gl_backend.c:21
void R_Mesh_DestroyFramebufferObject(int fbo)
void GL_ScissorTest(int state)
void gl_backend_init(void)
Definition gl_backend.c:340
unsigned int GL_Backend_CompileProgram(int vertexstrings_count, const char **vertexstrings_list, int geometrystrings_count, const char **geometrystrings_list, int fragmentstrings_count, const char **fragmentstrings_list)
void GL_Draw_Init(void)
Definition gl_draw.c:746
static const int nomodelelement3i[24]
Definition gl_rmain.c:6172
rtexture_t * r_texture_whitecube
Definition gl_rmain.c:277
static void R_DecalSystem_ApplySplatEntitiesQueue(void)
Definition gl_rmain.c:9557
void R_FrameData_SetMark(void)
set a marker that allows you to discard the following temporary memory allocations
Definition gl_rmain.c:3581
static int R_DrawBrushModelsSky(void)
only used if skyrendermasked, and normally returns false
Definition gl_rmain.c:4058
void R_Mesh_AddPolygon3f(rmesh_t *mesh, int numvertices, float *vertex3f)
Definition gl_rmain.c:6349
cvar_t r_shadows_castfrombmodels
Definition gl_rmain.c:128
@ SHADERSTATICPARM_POSTPROCESS_USERVEC4
postprocess uservec4 is enabled
Definition gl_rmain.c:840
@ SHADERSTATICPARM_SHADOWSAMPLER
sampler
Definition gl_rmain.c:845
@ SHADERSTATICPARM_EXACTSPECULARMATH
(lightsource or deluxemapping) use exact reflection map for specular effects, as opposed to the usual...
Definition gl_rmain.c:836
@ SHADERSTATICPARM_CELOUTLINES
celoutline (depth buffer analysis to produce outlines)
Definition gl_rmain.c:847
@ SHADERSTATICPARM_VERTEXTEXTUREBLEND_USEBOTHALPHAS
Definition gl_rmain.c:841
@ SHADERSTATICPARM_SHADOWMAPPCF_1
PCF 1.
Definition gl_rmain.c:843
@ SHADERSTATICPARM_CELSHADING
celshading (alternative diffuse and specular math)
Definition gl_rmain.c:846
@ SHADERSTATICPARM_COLORFRINGE
colorfringe (chromatic aberration)
Definition gl_rmain.c:849
@ SHADERSTATICPARM_POSTPROCESS_USERVEC2
postprocess uservec2 is enabled
Definition gl_rmain.c:838
@ SHADERSTATICPARM_OFFSETMAPPING_USELOD
LOD for offsetmapping.
Definition gl_rmain.c:842
@ SHADERSTATICPARM_FXAA
fast approximate anti aliasing
Definition gl_rmain.c:848
@ SHADERSTATICPARM_POSTPROCESS_USERVEC1
postprocess uservec1 is enabled
Definition gl_rmain.c:837
@ SHADERSTATICPARM_SATURATION_REDCOMPENSATE
red compensation filter for saturation
Definition gl_rmain.c:835
@ SHADERSTATICPARM_SHADOWMAPPCF_2
PCF 2.
Definition gl_rmain.c:844
@ SHADERSTATICPARM_POSTPROCESS_USERVEC3
postprocess uservec3 is enabled
Definition gl_rmain.c:839
cvar_t r_buffermegs[R_BUFFERDATA_COUNT]
Definition gl_rmain.c:249
cvar_t r_showlighting
Definition gl_rmain.c:88
cvar_t r_shadows_shadowmapbias
Definition gl_rmain.c:131
void R_GLSL_Restart_f(cmd_state_t *cmd)
Definition gl_rmain.c:1394
unsigned short locboxelements[6 *2 *3]
Definition gl_rmain.c:9096
void R_SetupShader_Generic_NoTexture(qbool usegamma, qbool notrippy)
Definition gl_rmain.c:1488
rtexturepool_t * r_main_texturepool
Definition gl_rmain.c:43
static void R_LoadQWSkin(r_qwskincache_t *cache, const char *skinname)
Definition gl_rmain.c:6550
static const float nomodelvertex3f[6 *3]
Definition gl_rmain.c:6196
cvar_t r_motionblur_velocityfactor
Definition gl_rmain.c:65
void R_RenderView(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, int x, int y, int width, int height)
Definition gl_rmain.c:5637
static void R_Main_FreeViewCache(void)
Definition gl_rmain.c:2998
qbool R_CanSeeBox(int numsamples, vec_t eyejitter, vec_t entboxenlarge, vec_t entboxexpand, vec_t pad, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs)
Definition gl_rmain.c:3888
skinframe_t * R_SkinFrame_LoadInternalQuake(const char *name, int textureflags, int loadpantsandshirt, int loadglowtexture, const unsigned char *skindata, int width, int height)
Definition gl_rmain.c:2616
void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const msurface_t **texturesurfacelist)
Definition gl_rmain.c:7416
int r_decalsystem_numqueued
Definition gl_rmain.c:9538
void R_ResetViewRendering2D(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight)
Definition gl_rmain.c:4477
static void R_BuildWhiteCube(void)
Definition gl_rmain.c:401
static void R_DrawModelDecals_Entity(entity_render_t *ent)
Definition gl_rmain.c:9637
r_rendertarget_t * R_RenderTarget_Get(int texturewidth, int textureheight, textype_t depthtextype, qbool depthisrenderbuffer, textype_t colortextype0, textype_t colortextype1, textype_t colortextype2, textype_t colortextype3)
Definition gl_rmain.c:4564
#define BLENDFUNC_ALLOWS_FOG_HACK0
Definition gl_rmain.c:1519
cvar_t r_motionblur_minblur
Definition gl_rmain.c:63
cvar_t r_shadows_drawafterrtlighting
Definition gl_rmain.c:127
static void R_DrawEntityBBoxes_Callback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
Definition gl_rmain.c:6114
cvar_t r_showspriteedges
Definition gl_rmain.c:93
void R_RenderView_UpdateViewVectors(void)
Definition gl_rmain.c:4512
static void R_BlendView(rtexture_t *viewcolortexture, int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, int x, int y, int width, int height)
Definition gl_rmain.c:5317
void R_EntityMatrix(const matrix4x4_t *matrix)
Definition gl_rmain.c:4417
void R_FrameData_ReturnToMark(void)
discard recent memory allocations (rewind to marker)
Definition gl_rmain.c:3588
cvar_t r_water_hideplayer
Definition gl_rmain.c:200
void R_FrameData_Reset(void)
free all R_FrameData memory
Definition gl_rmain.c:3493
skinframe_t * R_SkinFrame_LoadInternalUsingTexture(const char *name, int textureflags, rtexture_t *tex, int width, int height, qbool sRGB)
Definition gl_rmain.c:2840
int r_shadow_shadowmappcf
Definition r_shadow.c:60
cvar_t r_hdr_irisadaptation_fade_up
Definition gl_rmain.c:225
void Render_Init(void)
Definition gl_rmain.c:3420
cvar_t r_glsl_offsetmapping_reliefmapping_steps
Definition gl_rmain.c:175
cvar_t r_q1bsp_lightmap_updates_enabled
Definition gl_rmain.c:257
static void R_DrawLoc_Callback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
Definition gl_rmain.c:9106
#define R_MESH_PLANE_DIST_EPSILON
Definition gl_rmain.c:6391
void R_DecalSystem_Reset(decalsystem_t *decalsystem)
Definition gl_rmain.c:9162
cvar_t r_batch_dynamicbuffer
Definition gl_rmain.c:240
#define R_BUFFERDATA_CYCLE
Definition gl_rmain.c:3598
cvar_t r_hdr_irisadaptation_value
Definition gl_rmain.c:224
cvar_t r_hdr_irisadaptation_minvalue
Definition gl_rmain.c:222
static void R_SortEntities(void)
Definition gl_rmain.c:5620
unsigned int r_maxqueries
Definition gl_rmain.c:299
cvar_t r_hdr_irisadaptation_fade_down
Definition gl_rmain.c:226
cvar_t r_drawfog
Definition gl_rmain.c:139
float RSurf_FogVertex(const float *v)
Definition gl_rmain.c:7352
rtexture_t * r_texture_grey128
Definition gl_rmain.c:274
memexpandablearray_t r_glsl_permutationarray
storage for permutations linked in the hash table
Definition gl_rmain.c:938
#define R_COMPILESHADER_STATICPARM_ENABLE(p)
Definition gl_rmain.c:857
rtexture_t * r_shadow_prepasslightingdiffusetexture
Definition r_shadow.c:121
void R_SetupShader_DepthOrShadow(qbool notrippy, qbool depthrgb, qbool skeletal)
Definition gl_rmain.c:1493
cvar_t r_motionblur
Definition gl_rmain.c:59
cvar_t r_drawdecals
cvar_t r_bloom_colorsubtract
Definition gl_rmain.c:215
cvar_t r_shadows_focus
Definition gl_rmain.c:129
static qbool r_savedds
Definition gl_rmain.c:51
cvar_t r_fullbrights
Definition gl_rmain.c:122
rtexture_t * r_texture_fogattenuation
Definition gl_rmain.c:279
skinframe_t * decalskinframe
cvar_t r_viewscale_fpsscaling_stepsize
Definition gl_rmain.c:166
static char * R_ShaderStrCat(const char **strings)
Definition gl_rmain.c:965
static qbool r_gpuskeletal
Definition gl_rmain.c:52
cvar_t r_fullbright_directed_pitch_relative
Definition gl_rmain.c:118
cvar_t r_nolerp_list
Definition gl_rmain.c:204
cvar_t r_usedepthtextures
Definition gl_rmain.c:159
cvar_t r_bloom_colorexponent
Definition gl_rmain.c:214
cvar_t r_shadows_darken
Definition gl_rmain.c:124
cvar_t r_glsl_postprocess_uservec1_enable
Definition gl_rmain.c:185
void R_RenderScene(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight)
Definition gl_rmain.c:5834
cvar_t r_water_clippingplanebias
Definition gl_rmain.c:194
qbool R_AnimCache_GetEntity(entity_render_t *ent, qbool wantnormals, qbool wanttangents)
get the skeletal data or cached animated mesh data for an entity (optionally with normals and tangent...
Definition gl_rmain.c:3789
r_skinframe_t r_skinframe
Definition gl_rmain.c:2166
static void R_DrawModelsDebug(void)
Definition gl_rmain.c:4112
static void R_CalcTexCoordsForView(float x, float y, float w, float h, float tw, float th, float *texcoord2f)
Definition gl_rmain.c:4547
shadermodeinfo_t shadermodeinfo[SHADERLANGUAGE_COUNT][SHADERMODE_COUNT]
Definition gl_rmain.c:662
static rtexture_t * R_LoadCubemap(const char *basename)
Definition gl_rmain.c:2908
cvar_t r_lockvisibility
Definition gl_rsurf.c:30
cvar_t r_q1bsp_skymasking
Definition gl_rmain.c:132
rtexture_t * r_shadow_prepasslightingspeculartexture
Definition r_shadow.c:122
cvar_t r_draw2d
Definition gl_rmain.c:97
cvar_t r_transparent_sortmaxdist
Definition gl_rmain.c:142
void R_DrawCustomSurface(skinframe_t *skinframe, const matrix4x4_t *texmatrix, int materialflags, int firstvertex, int numvertices, int firsttriangle, int numtriangles, qbool writedepth, qbool prepass, qbool ui)
Definition gl_rmain.c:10208
cvar_t r_smoothnormals_areaweighting
Definition gl_rmain.c:229
static void R_SkinFrame_GenerateTexturesFromQPixels(skinframe_t *skinframe, qbool colormapped)
Definition gl_rmain.c:2676
#define FOGWIDTH
int r_maxsurfacelist
Definition gl_rmain.c:10024
void R_SkinFrame_PrepareForPurge(void)
Definition gl_rmain.c:2168
cvar_t r_fullbright_directed_diffuse
Definition gl_rmain.c:116
cvar_t r_test
Definition gl_rmain.c:235
void R_SetupShader_Generic(rtexture_t *t, qbool usegamma, qbool notrippy, qbool suppresstexalpha)
Definition gl_rmain.c:1461
cvar_t r_bloom
Definition gl_rmain.c:208
cvar_t r_shadows_throwdirection
Definition gl_rmain.c:126
cvar_t r_transparent_useplanardistance
Definition gl_rmain.c:81
rtexture_t * r_texture_black
Definition gl_rmain.c:275
void RSurf_DrawBatch(void)
Definition gl_rmain.c:8505
static r_qwskincache_t * r_qwskincache
Definition gl_rmain.c:308
cvar_t r_motionblur_velocityfactor_minspeed
Definition gl_rmain.c:66
int r_textureframe
used only by R_GetCurrentTexture, incremented per view and per UI render
Definition gl_rmain.c:45
cvar_t r_celoutlines
Definition gl_rmain.c:145
cvar_t r_glsl_deluxemapping
Definition gl_rmain.c:171
static void gl_main_start(void)
Definition gl_rmain.c:3041
static r_bufferdata_buffer_t * r_bufferdata_buffer[R_BUFFERDATA_CYCLE][R_BUFFERDATA_COUNT]
Definition gl_rmain.c:3610
cvar_t r_q1bsp_lightmap_updates_hidden_surfaces
Definition gl_rmain.c:259
static void R_DecalSystem_SpawnTriangle(decalsystem_t *decalsystem, const float *v0, const float *v1, const float *v2, const float *t0, const float *t1, const float *t2, const float *c0, const float *c1, const float *c2, int triangleindex, int surfaceindex, unsigned int decalsequence)
Definition gl_rmain.c:9169
static void R_DrawModelTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qbool writedepth, qbool prepass, qbool ui)
Definition gl_rmain.c:8860
static void R_BuildBlankTextures(void)
Definition gl_rmain.c:371
void R_RenderWaterPlanes(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight)
Definition gl_rmain.c:5803
static void R_DrawModelsAddWaterPlanes(void)
Definition gl_rmain.c:4127
cvar_t r_showtris
Definition gl_rmain.c:86
r_refdef_scene_t * R_GetScenePointer(r_refdef_scene_type_t scenetype)
Definition gl_rmain.c:5588
#define BLENDFUNC_ALLOWS_FOG_HACKALPHA
Definition gl_rmain.c:1520
qbool r_loadfog
Definition gl_rmain.c:49
r_glsl_permutation_t * r_glsl_permutation
currently selected permutation
Definition gl_rmain.c:936
float viewscalefpsadjusted
Definition gl_rmain.c:4382
int r_texture_numcubemaps
Definition gl_rmain.c:294
void R_FillColors(float *out, int verts, float r, float g, float b, float a)
Definition gl_rmain.c:335
void R_Mesh_AddBrushMeshFromPlanes(rmesh_t *mesh, int numplanes, mplane_t *planes)
Definition gl_rmain.c:6392
cvar_t r_viewscale_fpsscaling_stepmax
Definition gl_rmain.c:167
void R_BufferData_NewFrame(void)
begin a new frame (recycle old buffers)
Definition gl_rmain.c:3678
cvar_t r_viewscale
Definition gl_rmain.c:162
static void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
Definition gl_rmain.c:6216
qbool r_shadow_usingdeferredprepass
Definition r_shadow.c:64
static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, const msurface_t **texturesurfacelist, qbool writedepth, qbool prepass, qbool ui)
Definition gl_rmain.c:8714
cvar_t r_shadows
Definition gl_rmain.c:123
void R_ResetViewRendering3D(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight)
Definition gl_rmain.c:4482
cvar_t r_showcollisionbrushes_polygonfactor
Definition gl_rmain.c:90
static qbool R_BlendView_IsTrivial(int viewwidth, int viewheight, int width, int height)
Definition gl_rmain.c:5224
static void R_DrawLocs(void)
Definition gl_rmain.c:9149
static void R_Bloom_StartFrame(void)
Definition gl_rmain.c:5019
cvar_t r_motionblur_velocityfactor_maxspeed
Definition gl_rmain.c:67
void FOG_clear(void)
Definition gl_rmain.c:349
float RSurf_FogPoint(const float *v)
Definition gl_rmain.c:7336
void R_UpdateFog(void)
Definition gl_rmain.c:5396
cvar_t gl_fogdensity
Definition gl_rmain.c:148
cvar_t r_cullentities_trace
Definition gl_rmain.c:101
cvar_t r_colorfringe
Definition gl_rmain.c:189
static void R_DecalSystem_SplatTriangle(decalsystem_t *decalsystem, float r, float g, float b, float a, float s1, float t1, float s2, float t2, unsigned int decalsequence, qbool dynamic, float(*planes)[4], matrix4x4_t *projection, int triangleindex, int surfaceindex)
Definition gl_rmain.c:9249
cvar_t r_water_scissormode
Definition gl_rmain.c:198
cvar_t r_polygonoffset_decals_factor
Definition gl_rmain.c:135
skinframe_t * R_SkinFrame_LoadExternal(const char *name, int textureflags, qbool complain, qbool fallbacknotexture)
Definition gl_rmain.c:2314
cvar_t gl_fogblue
Definition gl_rmain.c:151
cvar_t r_hdr_irisadaptation_maxvalue
Definition gl_rmain.c:223
cvar_t r_viewscale_fpsscaling_target
Definition gl_rmain.c:168
const float r_screenvertex3f[12]
vertex coordinates for a quad that covers the screen exactly
Definition gl_rmain.c:313
void V_MakeViewIsometric(void)
Definition view.c:968
rtexture_t * r_texture_notexture
Definition gl_rmain.c:276
static void R_BufferData_Resize(r_bufferdata_type_t type, qbool mustgrow, size_t minsize)
Definition gl_rmain.c:3636
cvar_t gl_picmip
Definition gl_textures.c:29
cvar_t r_viewscale_fpsscaling_min
Definition gl_rmain.c:164
static void RSurf_RenumberElements(const int *inelement3i, int *outelement3i, int numelements, int adjust)
Definition gl_rmain.c:7408
cvar_t r_drawparticles
void R_HDR_UpdateIrisAdaptation(const vec3_t point)
Definition gl_rmain.c:4144
r_framebufferstate_t r_fb
Definition gl_rmain.c:265
cvar_t r_water_resolutionmultiplier
Definition gl_rmain.c:195
skinframe_t * R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, const unsigned char *skindata, int width, int height, int comparewidth, int compareheight, int comparecrc, qbool sRGB)
Definition gl_rmain.c:2546
float locboxvertex3f[6 *4 *3]
Definition gl_rmain.c:9086
matrix4x4_t r_waterscrollmatrix
Definition gl_rmain.c:5394
static void R_FrameData_Resize(qbool mustgrow)
Definition gl_rmain.c:3503
cvar_t r_glsl_offsetmapping_reliefmapping_refinesteps
Definition gl_rmain.c:176
qbool r_shadow_shadowmapsampler
Definition r_shadow.c:58
static void R_BuildNormalizationCube(void)
Definition gl_rmain.c:408
rtexture_t * r_texture_reflectcube
Definition gl_rmain.c:284
cvar_t v_glslgamma_2d
Definition vid_shared.c:186
cvar_t r_water_refractdistort
Definition gl_rmain.c:196
static void R_MotionBlurView(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight)
Definition gl_rmain.c:5251
static float irisvecs[7][3]
Definition gl_rmain.c:4142
void R_SetupShader_DeferredLight(const rtlight_t *rtlight)
Definition gl_rmain.c:2091
void R_UpdateVariables(void)
Definition gl_rmain.c:5483
cvar_t v_isometric
Definition view.c:97
void * R_FrameData_Alloc(size_t size)
allocate some temporary memory for your purposes
Definition gl_rmain.c:3539
static int RSurf_FindWaterPlaneForSurface(const msurface_t *surface)
Definition gl_rmain.c:8564
rsurfacestate_t rsurface
Definition gl_rmain.c:6947
cvar_t r_glsl_vertextextureblend_usebothalphas
Definition gl_rmain.c:245
cvar_t r_farclip_world
Definition gl_rmain.c:75
skinframe_t * R_SkinFrame_Find(const char *name, int textureflags, int comparewidth, int compareheight, int comparecrc, qbool add)
Definition gl_rmain.c:2240
cvar_t r_drawportals
Definition gl_rmain.c:95
void R_RenderTarget_FreeUnused(qbool force)
Definition gl_rmain.c:4523
static const unsigned short bboxelements[36]
Definition gl_rmain.c:6030
r_decalsystem_splatqueue_t r_decalsystem_queue[MAX_DECALSYSTEM_QUEUE]
Definition gl_rmain.c:9539
cvar_t r_waterscroll
Definition gl_rmain.c:206
cvar_t r_cullentities_trace_eyejitter
Definition gl_rmain.c:109
static void R_SetupShader_SetPermutationGLSL(unsigned int mode, uint64_t permutation)
Definition gl_rmain.c:1346
skinframe_t * R_SkinFrame_LoadNoTexture(void)
Definition gl_rmain.c:2832
cvar_t r_glsl_postprocess_uservec3_enable
Definition gl_rmain.c:187
static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode, uint64_t permutation)
Definition gl_rmain.c:1024
unsigned int r_texture_gammaramps_serial
Definition gl_rmain.c:282
cvar_t r_polygonoffset_decals_offset
Definition gl_rmain.c:136
static void gl_main_newmap(void)
Definition gl_rmain.c:3194
cvar_t r_bloom_scenebrightness
Definition gl_rmain.c:216
static const float bboxedges[BBOXEDGES][6]
Definition gl_rmain.c:6041
void R_Water_AddWaterPlane(msurface_t *surface, int entno)
Definition gl_rmain.c:4640
cvar_t r_celshading
Definition gl_rmain.c:144
static void R_View_Update(const int *myscissor)
Definition gl_rmain.c:4374
void R_SkinFrame_Purge(void)
Definition gl_rmain.c:2203
mempool_t * r_main_mempool
Definition gl_rmain.c:42
void GL_Main_Init(void)
Definition gl_rmain.c:3220
static void R_View_UpdateEntityVisible(void)
Definition gl_rmain.c:3992
cvar_t r_fullbright
Definition gl_rmain.c:112
#define SKINFRAME_HASH
Definition gl_rmain.c:2157
cvar_t r_bloom_colorscale
Definition gl_rmain.c:209
unsigned int r_numqueries
Definition gl_rmain.c:298
#define NORMSIZE
cvar_t r_motionblur_mousefactor
Definition gl_rmain.c:68
rtexture_t * r_texture_blanknormalmap
Definition gl_rmain.c:272
cvar_t r_transparent_sortsurfacesbynearest
Definition gl_rmain.c:80
qbool v_flipped_state
Definition gl_backend.c:17
static char * ShaderModeInfo_GetShaderText(shadermodeinfo_t *modeinfo, qbool printfromdisknotice, qbool builtinonly)
Definition gl_rmain.c:1006
texture_t * R_GetCurrentTexture(texture_t *t)
Definition gl_rmain.c:6577
static const char * shaderstaticparmstrings_list[SHADERSTATICPARMS_COUNT]
Definition gl_rmain.c:853
cvar_t r_showoverdraw
Definition gl_rmain.c:82
cvar_t r_glsl_offsetmapping
Definition gl_rmain.c:172
cvar_t r_batch_multidraw_mintriangles
Definition gl_rmain.c:238
rtexture_t * r_texture_fogheighttexture
Definition gl_rmain.c:280
void R_AnimCache_Free(void)
Animation cache prevents re-generating mesh data for an animated model multiple times in one frame fo...
Definition gl_rmain.c:3758
void R_SelectScene(r_refdef_scene_type_t scenetype)
Definition gl_rmain.c:5573
static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qbool writedepth, qbool depthonly, qbool prepass, qbool ui)
Definition gl_rmain.c:9006
static void R_DrawModels(void)
Definition gl_rmain.c:4078
cvar_t r_water_lowquality
Definition gl_rmain.c:199
static void R_DrawModelDecals_FadeEntity(entity_render_t *ent)
Definition gl_rmain.c:9568
cvar_t r_cullentities_trace_tempentitysamples
Definition gl_rmain.c:104
cvar_t r_cullentities_trace_delay
Definition gl_rmain.c:108
static const unsigned short nomodelelement3s[24]
Definition gl_rmain.c:6184
#define BBOXEDGES
Definition gl_rmain.c:6040
static void R_Bloom_MakeTexture(void)
Definition gl_rmain.c:5113
cvar_t r_bloom_resolution
Definition gl_rmain.c:213
void R_ResetViewRendering2D_Common(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight, float x2, float y2)
Definition gl_rmain.c:4439
cvar_t r_hdr_irisadaptation
Definition gl_rmain.c:220
cvar_t gl_fogenable
Definition gl_rmain.c:147
void RSurf_SetupDepthAndCulling(bool ui)
Definition gl_rmain.c:8604
static void R_View_SetFrustum(const int *scissor)
Definition gl_rmain.c:4189
svbsp_t r_svbsp
shadow volume bsp struct with automatically growing nodes buffer
Definition gl_rmain.c:268
static void R_GetCornerOfBox(vec3_t out, const vec3_t mins, const vec3_t maxs, int signbits)
Definition gl_rmain.c:3438
static void R_tcMod_ApplyToMatrix(matrix4x4_t *texmatrix, q3shaderinfo_layer_tcmod_t *tcmod, int currentmaterialflags)
Definition gl_rmain.c:6473
cvar_t r_fullbright_directed
Definition gl_rmain.c:114
cvar_t r_drawentities
Definition gl_rmain.c:96
cvar_t r_dynamic
Definition gl_rmain.c:121
cvar_t r_useinfinitefarclip
Definition gl_rmain.c:73
cvar_t r_bloom_brighten
Definition gl_rmain.c:211
cvar_t r_shadows_shadowmapscale
Definition gl_rmain.c:130
cvar_t cl_locs_show
Definition cl_main.c:98
cvar_t r_batch_multidraw
Definition gl_rmain.c:237
static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, const msurface_t **texturesurfacelist)
Definition gl_rmain.c:8615
int r_uniformbufferalignment
Definition gl_rmain.c:270
#define SHADERSTATICPARMS_COUNT
Definition gl_rmain.c:851
cvar_t r_hdr_scenebrightness
Definition gl_rmain.c:218
static void R_QueueModelSurfaceList(entity_render_t *ent, int numsurfaces, const msurface_t **surfacelist, int flagsmask, qbool writedepth, qbool depthonly, qbool prepass, qbool ui)
Definition gl_rmain.c:9040
static r_refdef_scene_type_t r_currentscenetype
Definition gl_rmain.c:5566
static void R_ProcessTransparentTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist)
Definition gl_rmain.c:8961
rtexture_t * R_GetCubemap(const char *basename)
Definition gl_rmain.c:2982
qbool R_CullBox(const vec3_t mins, const vec3_t maxs, int numplanes, const mplane_t *planes)
Definition gl_rmain.c:3470
shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT]
Definition gl_rmain.c:625
cvar_t r_motionblur_maxblur
Definition gl_rmain.c:64
cvar_t r_motionblur_averaging
Definition gl_rmain.c:61
cvar_t r_fxaa
Definition gl_rmain.c:190
cvar_t r_fullbright_directed_ambient
Definition gl_rmain.c:115
cvar_t r_transparent_sortarraysize
Definition gl_rmain.c:143
#define R_COMPILESHADER_STATICPARM_EMIT(p, n)
Definition gl_rmain.c:906
cvar_t r_motionblur_mousefactor_maxspeed
Definition gl_rmain.c:70
qbool R_CompileShader_CheckStaticParms(void)
Definition gl_rmain.c:861
static qbool r_loadnormalmap
Definition gl_rmain.c:47
static void R_DecalSystem_ApplySplatEntities(const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize, unsigned int decalsequence)
Definition gl_rmain.c:9501
cvar_t r_showparticleedges
Definition gl_rmain.c:94
cvar_t r_fullbright_directed_pitch
Definition gl_rmain.c:117
cvar_t r_water_reflectdistort
Definition gl_rmain.c:197
cvar_t r_showsurfaces
Definition gl_rmain.c:85
skinframe_t * R_SkinFrame_FindNextByName(skinframe_t *last, const char *name)
Definition gl_rmain.c:2217
cvar_t r_motionblur_mousefactor_minspeed
Definition gl_rmain.c:69
cvar_t gl_fogstart
Definition gl_rmain.c:152
cvar_t r_hdr_irisadaptation_radius
Definition gl_rmain.c:227
static void R_CompileShader_AddStaticParms(unsigned int mode, uint64_t permutation)
Definition gl_rmain.c:911
cvar_t r_polygonoffset_submodel_factor
Definition gl_rmain.c:133
static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, int viewx, int viewy, int viewwidth, int viewheight)
Definition gl_rmain.c:4757
void R_AnimCache_ClearCache(void)
clear the animcache pointers on all known render entities
Definition gl_rmain.c:3762
cvar_t r_drawexteriormodel
Definition gl_rmain.c:100
cubemapinfo_t * r_texture_cubemaps[MAX_CUBEMAPS]
Definition gl_rmain.c:295
void R_DebugLine(vec3_t start, vec3_t end)
Definition gl_rmain.c:10163
static int componentorder[4]
Definition gl_rmain.c:2906
static qbool _R_CullBox(const vec3_t mins, const vec3_t maxs, int numplanes, const mplane_t *planes, int ignore)
Definition gl_rmain.c:3445
cvar_t developer_texturelogging
Definition gl_rmain.c:231
void R_CalcBeam_Vertex3f(float *vert, const float *org1, const float *org2, float width)
Definition gl_rmain.c:6281
static const int quadedges[6][2]
Definition gl_rmain.c:7415
cvar_t r_viewscale_fpsscaling_multiply
Definition gl_rmain.c:165
cvar_t r_water
Definition gl_rmain.c:192
const msurface_t ** r_surfacelist
Definition gl_rmain.c:10025
cvar_t r_glsl_offsetmapping_lod
Definition gl_rmain.c:178
void R_BufferData_Reset(void)
frees all dynamic buffers
Definition gl_rmain.c:3613
void R_CalcSprite_Vertex3f(float *vertex3f, const vec3_t origin, const vec3_t left, const vec3_t up, float scalex1, float scalex2, float scaley1, float scaley2)
Definition gl_rmain.c:6311
#define R_SKINFRAME_LOAD_AVERAGE_COLORS(cnt, getpixel)
Definition gl_rmain.c:2279
cvar_t r_glsl_offsetmapping_scale
Definition gl_rmain.c:177
cvar_t r_showbboxes
Definition gl_rmain.c:83
cvar_t r_batch_debugdynamicvertexpath
Definition gl_rmain.c:239
void RSurf_UploadBuffersForBatch(void)
Definition gl_rmain.c:7368
static void R_InitShaderModeInfo(void)
Definition gl_rmain.c:987
void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
Definition gl_rmain.c:321
static int r_bufferdata_cycle
Definition gl_rmain.c:3609
cvar_t cl_decals_models
cvar_t r_shadows_throwdistance
Definition gl_rmain.c:125
void R_DrawModelSurfaces(entity_render_t *ent, qbool skysurfaces, qbool writedepth, qbool depthonly, qbool debug, qbool prepass, qbool ui)
Definition gl_rmain.c:10026
cvar_t r_lockpvs
Definition gl_rsurf.c:29
static unsigned int r_compileshader_staticparms[(SHADERSTATICPARMS_COUNT+0x1F) > > 5]
Definition gl_rmain.c:856
void R_SkinFrame_PurgeSkinFrame(skinframe_t *s)
Definition gl_rmain.c:2184
cvar_t gl_lightmaps
Definition gl_rmain.c:233
cvar_t r_transparent_sortmindist
Definition gl_rmain.c:141
cvar_t r_cullentities_trace_samples
Definition gl_rmain.c:103
cvar_t r_showbboxes_client
Definition gl_rmain.c:84
#define RAMPWIDTH
skinframe_t * R_SkinFrame_LoadMissing(void)
Definition gl_rmain.c:2804
cvar_t r_framedatasize
Definition gl_rmain.c:248
cvar_t r_wateralpha
Definition gl_rmain.c:120
cvar_t r_glsl_postprocess_uservec2_enable
Definition gl_rmain.c:186
void R_SetupView(qbool allowwaterclippingplane, int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight)
Definition gl_rmain.c:4384
cvar_t r_showcollisionbrushes
Definition gl_rmain.c:89
void RSurf_ActiveModelEntity(const entity_render_t *ent, qbool wantnormals, qbool wanttangents, qbool prepass)
Definition gl_rmain.c:6949
cvar_t r_fog_clear
Definition gl_rmain.c:138
cvar_t r_damageblur
Definition gl_rmain.c:60
cvar_t r_fog_exp2
Definition gl_rmain.c:137
static void R_BuildFogTexture(void)
Definition gl_rmain.c:470
cvar_t r_glsl_postprocess_uservec4
Definition gl_rmain.c:184
static r_glsl_permutation_t * R_GLSL_FindPermutation(unsigned int mode, uint64_t permutation)
Definition gl_rmain.c:940
cvar_t gl_fogred
Definition gl_rmain.c:149
skinframe_t * R_SkinFrame_LoadExternal_SkinFrame(skinframe_t *skinframe, const char *name, int textureflags, qbool complain, qbool fallbacknotexture)
Definition gl_rmain.c:2331
int r_shadow_shadowmapatlas_modelshadows_size
Definition r_shadow.c:69
cvar_t r_cullentities_trace_expand
Definition gl_rmain.c:106
static void R_Mesh_AddPolygon3d(rmesh_t *mesh, int numvertices, double *vertex3d)
Definition gl_rmain.c:6370
static int shaderstaticparms_count
Definition gl_rmain.c:854
r_glsl_permutation_t * r_glsl_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE]
information about each possible shader permutation
Definition gl_rmain.c:934
cvar_t r_shownormals
Definition gl_rmain.c:87
cvar_t r_shadow_bouncegrid
Definition r_shadow.c:198
void R_SkinFrame_MarkUsed(skinframe_t *skinframe)
Definition gl_rmain.c:2176
cvar_t r_transparent
Definition gl_rmain.c:78
void R_DecalSystem_SplatEntities(const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize)
Definition gl_rmain.c:9541
cvar_t r_bloom_blur
Definition gl_rmain.c:212
cvar_t r_sortentities
Definition gl_rmain.c:110
cvar_t r_transparent_alphatocoverage
Definition gl_rmain.c:79
cvar_t cl_decals_bias
void R_FrameData_NewFrame(void)
prepare for a new frame, recycles old buffers if a resize occurred previously
Definition gl_rmain.c:3521
cvar_t r_glsl_saturation_redcompensate
Definition gl_rmain.c:243
cvar_t r_glsl_offsetmapping_reliefmapping
Definition gl_rmain.c:174
cvar_t r_speeds
Definition gl_rmain.c:111
cvar_t r_polygonoffset_submodel_offset
Definition gl_rmain.c:134
static void gl_main_shutdown(void)
Definition gl_rmain.c:3138
#define BLENDFUNC_ALLOWS_FOG
Definition gl_rmain.c:1518
cvar_t r_showcollisionbrushes_polygonoffset
Definition gl_rmain.c:91
static r_refdef_scene_t r_scenes_store[RST_COUNT]
Definition gl_rmain.c:5567
cvar_t r_showdisabledepthtest
Definition gl_rmain.c:92
static void R_DrawDebugModel(void)
Definition gl_rmain.c:9803
cvar_t r_drawworld
Definition gl_rmain.c:98
cvar_t r_motionblur_randomize
Definition gl_rmain.c:62
#define BLENDFUNC_ALLOWS_COLORMOD
Definition gl_rmain.c:1517
void R_SetupShader_Surface(const float rtlightambient[3], const float rtlightdiffuse[3], const float rtlightspecular[3], rsurfacepass_t rsurfacepass, int texturenumsurfaces, const msurface_t **texturesurfacelist, void *surfacewaterplane, qbool notrippy, qbool ui)
Definition gl_rmain.c:1563
cvar_t r_drawviewmodel
Definition gl_rmain.c:99
static r_framedata_mem_t * r_framedata_mem
Definition gl_rmain.c:3491
cvar_t r_nearclip
Definition gl_rmain.c:76
#define SHADERPERMUTATION_HASHSIZE
Definition gl_rmain.c:828
cvar_t r_cullentities_trace_pad
Definition gl_rmain.c:107
cvar_t gl_fogend
Definition gl_rmain.c:153
static int R_Mesh_AddVertex(rmesh_t *mesh, float x, float y, float z)
Definition gl_rmain.c:6327
static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
Definition gl_rmain.c:8879
cvar_t r_cullentities_trace_enlarge
Definition gl_rmain.c:105
static void R_BuildNoTexture(void)
Definition gl_rmain.c:396
static const float nomodelcolor4f[6 *4]
Definition gl_rmain.c:6206
cvar_t r_glsl_postprocess_uservec4_enable
Definition gl_rmain.c:188
cvar_t r_hdr_irisadaptation_multiplier
Definition gl_rmain.c:221
cvar_t r_glsl_postprocess_uservec1
Definition gl_rmain.c:181
cvar_t r_lerpsprites
Definition gl_rmain.c:202
static qbool R_TestQ3WaveFunc(q3wavefunc_t func, const float *parms)
Definition gl_rmain.c:6425
cvar_t r_water_cameraentitiesonly
Definition gl_rmain.c:193
static void R_Water_StartFrame(int viewwidth, int viewheight)
Definition gl_rmain.c:4608
qbool R_CullFrustum(const vec3_t mins, const vec3_t maxs)
Definition gl_rmain.c:3464
static float R_EvaluateQ3WaveFunc(q3wavefunc_t func, const float *parms)
Definition gl_rmain.c:6435
cvar_t r_rendertarget_debug
Definition gl_rmain.c:161
rtexture_t * loadingscreentexture
Definition cl_screen.c:1598
cvar_t r_glsl_offsetmapping_steps
Definition gl_rmain.c:173
cvar_t r_q1bsp_lightmap_updates_combine
Definition gl_rmain.c:258
static void R_BuildFogHeightTexture(void)
Definition gl_rmain.c:526
rtexture_t * r_texture_gammaramps
Definition gl_rmain.c:281
static int R_SortEntities_Compare(const void *ap, const void *bp)
Definition gl_rmain.c:5598
static void R_DrawModelDecals(void)
Definition gl_rmain.c:9767
r_refdef_t r_refdef
Definition gl_rmain.c:57
static void R_Main_ResizeViewCache(void)
Definition gl_rmain.c:3011
static suffixinfo_t suffix[3][6]
Definition gl_rmain.c:2878
cvar_t r_texture_dds_load
Definition gl_rmain.c:156
cvar_t r_lerplightstyles
Definition gl_rmain.c:205
cvar_t r_depthfirst
Definition gl_rmain.c:72
cvar_t r_deformvertexes
Definition gl_rmain.c:77
rtexture_t * r_texture_white
Definition gl_rmain.c:273
cvar_t r_glsl_saturation
Definition gl_rmain.c:242
static int r_qwskincache_size
Definition gl_rmain.c:309
cvar_t gl_skyclip
Definition gl_rmain.c:154
cvar_t r_viewfbo
Definition gl_rmain.c:160
rtexture_t * r_texture_normalizationcube
Definition gl_rmain.c:278
cvar_t r_lerpmodels
Definition gl_rmain.c:203
static void R_GLSL_DumpShader_f(cmd_state_t *cmd)
Definition gl_rmain.c:1419
unsigned int r_shadow_occlusion_buf
Definition r_shadow.c:136
static void R_DrawModelsDepth(void)
Definition gl_rmain.c:4097
cvar_t r_farclip_base
Definition gl_rmain.c:74
cvar_t r_glsl_postprocess_uservec2
Definition gl_rmain.c:182
r_meshbuffer_t * R_BufferData_Store(size_t datasize, const void *data, r_bufferdata_type_t type, int *returnbufferoffset)
request space in a vertex/index/uniform buffer for the chosen data, returns the buffer pointer and of...
Definition gl_rmain.c:3707
cvar_t r_glsl_postprocess
Definition gl_rmain.c:180
void R_DrawCustomSurface_Texture(texture_t *texture, const matrix4x4_t *texmatrix, int materialflags, int firstvertex, int numvertices, int firsttriangle, int numtriangles, qbool writedepth, qbool prepass, qbool ui)
Definition gl_rmain.c:10228
static void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, float ca)
Definition gl_rmain.c:6062
static void R_DrawTextureSurfaceList_DepthOnly(int texturenumsurfaces, const msurface_t **texturesurfacelist)
Definition gl_rmain.c:8993
cvar_t r_hdr_glowintensity
Definition gl_rmain.c:219
void * R_FrameData_Store(size_t size, void *data)
allocate some temporary memory and copy this data into it
Definition gl_rmain.c:3573
cvar_t r_cullentities_trace_entityocclusion
Definition gl_rmain.c:102
void RSurf_ActiveCustomEntity(const matrix4x4_t *matrix, const matrix4x4_t *inversematrix, int entflags, double shadertime, float r, float g, float b, float a, int numvertices, const float *vertex3f, const float *texcoord2f, const float *normal3f, const float *svector3f, const float *tvector3f, const float *color4f, int numtriangles, const int *element3i, const unsigned short *element3s, qbool wantnormals, qbool wanttangents)
Definition gl_rmain.c:7174
#define BLENDFUNC_ALLOWS_ANYFOG
Definition gl_rmain.c:1521
cvar_t r_transparentdepthmasking
Definition gl_rmain.c:140
static qbool r_loadgloss
Definition gl_rmain.c:48
static void R_DrawNoModel(entity_render_t *ent)
Definition gl_rmain.c:6271
static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldorigin, const vec3_t worldnormal, float r, float g, float b, float a, float s1, float t1, float s2, float t2, float worldsize, unsigned int decalsequence)
Definition gl_rmain.c:9342
static const char * builtinshaderstrings[]
Definition gl_rmain.c:596
static qbool r_loaddds
Definition gl_rmain.c:50
cvar_t r_glsl_postprocess_uservec3
Definition gl_rmain.c:183
static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, const msurface_t **texturesurfacelist, qbool writedepth)
Definition gl_rmain.c:8774
cvar_t r_glsl_offsetmapping_lod_distance
Definition gl_rmain.c:179
skinframe_t * R_SkinFrame_LoadInternal8bit(const char *name, int textureflags, const unsigned char *skindata, int width, int height, const unsigned int *palette, const unsigned int *alphapalette)
Definition gl_rmain.c:2749
cvar_t r_glsl_skeletal
Definition gl_rmain.c:170
cvar_t gl_foggreen
Definition gl_rmain.c:150
cvar_t cl_decals_newsystem_intensitymultiplier
void R_AnimCache_CacheVisibleEntities(void)
generate animcache data for all entities marked visible
Definition gl_rmain.c:3874
static void R_DrawEntityBBoxes(prvm_prog_t *prog)
Definition gl_rmain.c:6148
cvar_t cl_decals_max
static int R_BlendFuncFlags(int src, int dst)
Definition gl_rmain.c:1522
unsigned int r_queries[MAX_OCCLUSION_QUERIES]
Definition gl_rmain.c:297
cvar_t r_viewscale_fpsscaling
Definition gl_rmain.c:163
cvar_t r_texture_dds_save
Definition gl_rmain.c:157
void GL_Surf_Init(void)
Definition gl_rsurf.c:1564
cvar_t r_ambient
Definition gl_rsurf.c:28
void R_BuildLightMap(const entity_render_t *ent, msurface_t *surface, int combine)
Definition gl_rsurf.c:50
void R_View_WorldVisibility(qbool forcenovis)
Definition gl_rsurf.c:436
void R_DrawPortals(void)
Definition gl_rsurf.c:381
cvar_t r_q3bsp_renderskydepth
Definition gl_rsurf.c:41
void R_PurgeTexture(rtexture_t *rt)
void R_FreeTexturePool(rtexturepool_t **rtexturepool)
int R_TextureFlags(rtexture_t *rt)
cvar_t gl_texturecompression_lightcubemaps
Definition gl_textures.c:46
cvar_t gl_texturecompression
Definition gl_textures.c:37
rtexture_t * R_LoadTextureRenderBuffer(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, textype_t textype)
void R_UpdateTexture(rtexture_t *rt, const unsigned char *data, int x, int y, int z, int width, int height, int depth, int combine)
cvar_t gl_texturecompression_reflectmask
Definition gl_textures.c:47
cvar_t gl_texturecompression_color
Definition gl_textures.c:38
rtexture_t * R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filename, qbool srgb, int flags, qbool *hasalphaflag, float *avgcolor, int miplevel, qbool optionaltexture)
int R_SaveTextureDDSFile(rtexture_t *rt, const char *filename, qbool skipuncompressed, qbool hasalpha)
cvar_t gl_texturecompression_glow
Definition gl_textures.c:41
rtexture_t * R_LoadTextureCubeMap(rtexturepool_t *rtexturepool, const char *identifier, int width, const unsigned char *data, textype_t textype, int flags, int miplevel, const unsigned int *palette)
rtexturepool_t * R_AllocTexturePool(void)
void R_FreeTexture(rtexture_t *rt)
void R_Textures_Init(void)
void R_Textures_Frame(void)
cvar_t gl_texturecompression_gloss
Definition gl_textures.c:40
int R_PicmipForFlags(int flags)
rtexture_t * R_LoadTexture2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, const unsigned char *data, textype_t textype, int flags, int miplevel, const unsigned int *palette)
cvar_t gl_texturecompression_normal
Definition gl_textures.c:39
GLuint GLuint GLintptr GLsizeiptr size
Definition glquake.h:631
GLubyte GLubyte GLubyte z
Definition glquake.h:781
GLenum GLenum GLuint texture
Definition glquake.h:612
#define GL_NONE
Definition glquake.h:127
GLenum GLsizei width
Definition glquake.h:621
GLenum GLsizei GLsizei height
Definition glquake.h:621
#define CHECKGLERROR
Definition glquake.h:1058
GLfloat GLfloat GLfloat v2
Definition glquake.h:746
GLint GLint GLint yoffset
Definition glquake.h:648
GLubyte GLubyte GLubyte GLubyte w
Definition glquake.h:781
#define GL_UNIFORM_BUFFER
Definition glquake.h:412
int GLint
Definition glquake.h:51
GLsizei samples
Definition glquake.h:622
GLenum mode
Definition glquake.h:717
GLsizei const GLfloat * value
Definition glquake.h:739
#define GL_FRONT_AND_BACK
Definition glquake.h:136
#define GL_POLYGON_OFFSET_FILL
Definition glquake.h:182
#define GL_ONE_MINUS_DST_ALPHA
Definition glquake.h:82
#define GL_ONE_MINUS_DST_COLOR
Definition glquake.h:78
const GLdouble * v
Definition glquake.h:761
#define GL_SRC_ALPHA
Definition glquake.h:79
GLint GLenum GLint GLint y
Definition glquake.h:650
#define GL_BACK
Definition glquake.h:133
#define GL_SRC_COLOR
Definition glquake.h:75
#define GL_FLOAT
Definition glquake.h:124
#define GL_ZERO
Definition glquake.h:73
GLint GLenum GLint x
Definition glquake.h:650
GLint GLint xoffset
Definition glquake.h:648
#define GL_UNSIGNED_BYTE
Definition glquake.h:119
GLsizeiptr const GLvoid * data
Definition glquake.h:638
GLfloat v0
Definition glquake.h:738
#define GL_LEQUAL
Definition glquake.h:161
GLfloat GLfloat v1
Definition glquake.h:742
unsigned int GLenum
Definition glquake.h:45
int GLsizei
Definition glquake.h:55
#define GL_COLOR_BUFFER_BIT
Definition glquake.h:170
#define GL_FILL
Definition glquake.h:108
GLuint GLuint GLintptr offset
Definition glquake.h:631
#define GL_ONE_MINUS_SRC_ALPHA
Definition glquake.h:80
#define GL_ONE
Definition glquake.h:74
GLint GLenum GLenum GLvoid * pixels
Definition glquake.h:705
#define GL_DST_ALPHA
Definition glquake.h:81
#define GL_LINE
Definition glquake.h:107
const GLchar * name
Definition glquake.h:600
#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT
Definition glquake.h:425
#define GL_DST_COLOR
Definition glquake.h:77
#define GL_FRONT
Definition glquake.h:132
GLclampf GLclampf GLclampf alpha
Definition glquake.h:641
GLsizei const GLchar ** string
Definition glquake.h:727
#define GL_ACTIVE_UNIFORMS
Definition glquake.h:453
#define GL_DEPTH_BUFFER_BIT
Definition glquake.h:168
GLuint index
Definition glquake.h:628
#define GL_ONE_MINUS_SRC_COLOR
Definition glquake.h:76
GLenum type
Definition glquake.h:655
host_static_t host
Definition host.c:41
cvar_t developer_extra
Definition host.c:49
cvar_t developer_loading
Definition host.c:52
unsigned char * Image_GenerateNoTexture(void)
Definition image.c:1887
int image_height
Definition image.c:10
void Image_HeightmapToNormalmap_BGRA(const unsigned char *inpixels, unsigned char *outpixels, int width, int height, int clamp, float bumpscale)
Definition image.c:1769
void Image_Copy8bitBGRA(const unsigned char *in, unsigned char *out, int pixels, const unsigned int *pal)
Definition image.c:129
void Image_CopyMux(unsigned char *outpixels, const unsigned char *inpixels, int inputwidth, int inputheight, qbool inputflipx, qbool inputflipy, qbool inputflipdiagonal, int numoutputcomponents, int numinputcomponents, int *outputinputcomponentindices)
Definition image.c:24
unsigned char * loadimagepixelsbgra(const char *filename, qbool complain, qbool allowFixtrans, qbool convertsRGB, int *miplevel)
Definition image.c:1043
qbool LoadPCX_QWSkin(const unsigned char *f, int filesize, unsigned char *pixels, int outwidth, int outheight)
Definition image.c:286
int image_width
Definition image.c:9
void Image_StripImageExtension(const char *in, char *out, size_t size_out)
Definition image.c:913
#define Image_sRGBFloatFromLinearFloat(c)
Definition image.h:68
vec3_t vec3_origin
Definition mathlib.c:26
int LoopingFrameNumberFromDouble(double t, int loopframes)
Definition mathlib.c:891
void AnglesFromVectors(vec3_t angles, const vec3_t forward, const vec3_t up, qbool flippitch)
LadyHavoc: calculates pitch/yaw/roll angles from forward and up vectors.
Definition mathlib.c:650
void AngleVectors(const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
Definition mathlib.c:444
void PlaneClassify(mplane_t *p)
Definition mathlib.c:310
#define VectorReflect(a, r, b, c)
Definition mathlib.h:120
#define Vector4Set(a, b, c, d, e)
Definition mathlib.h:85
#define VectorMAMAMAM(scale1, b1, scale2, b2, scale3, b3, scale4, b4, c)
Definition mathlib.h:117
#define max(A, B)
Definition mathlib.h:38
#define VectorNegate(a, b)
Definition mathlib.h:94
#define min(A, B)
Definition mathlib.h:37
#define BoxesOverlap(a, b, c, d)
Definition mathlib.h:121
#define VectorNormalize(v)
Definition mathlib.h:103
#define VectorLerp(v1, lerp, v2, c)
Definition mathlib.h:119
#define VectorClear(a)
Definition mathlib.h:96
#define bound(min, num, max)
Definition mathlib.h:34
#define VectorLength(a)
Definition mathlib.h:108
#define lhrandom(MIN, MAX)
LadyHavoc: this function never returns exactly MIN or exactly MAX, because of a QuakeC bug in id1 whe...
Definition mathlib.h:48
#define Vector4Copy(a, b)
Definition mathlib.h:83
#define VectorLength2(a)
Definition mathlib.h:109
#define Vector4Clear(a)
Definition mathlib.h:81
#define VectorDistance2(a, b)
Definition mathlib.h:106
#define CrossProduct(a, b, c)
Definition mathlib.h:102
#define VectorMAM(scale1, b1, scale2, b2, c)
Definition mathlib.h:115
#define VectorCompare(a, b)
Definition mathlib.h:112
#define TriangleNormal(a, b, c, n)
Definition mathlib.h:125
#define PlaneDiff(point, plane)
Definition mathlib.h:256
#define VectorDistance(a, b)
Definition mathlib.h:107
#define VectorAdd(a, b, c)
Definition mathlib.h:99
#define DotProduct(a, b)
Definition mathlib.h:97
#define VectorCopy(a, b)
Definition mathlib.h:100
#define VectorSet(a, b, c, d)
Definition mathlib.h:95
#define Vector4Add(a, b, c)
Definition mathlib.h:88
#define VectorSubtract(a, b, c)
Definition mathlib.h:98
#define VectorScale(in, scale, out)
Definition mathlib.h:110
#define VectorMA(a, scale, b, c)
Definition mathlib.h:113
#define VectorMAMAM(scale1, b1, scale2, b2, scale3, b3, c)
Definition mathlib.h:116
#define M_PI
Definition mathlib.h:28
#define Vector4Multiply(a, b, c)
Definition mathlib.h:90
void Matrix4x4_Concat(matrix4x4_t *out, const matrix4x4_t *in1, const matrix4x4_t *in2)
Definition matrixlib.c:83
void Matrix4x4_CreateIdentity(matrix4x4_t *out)
Definition matrixlib.c:564
void Matrix4x4_TransformStandardPlane(const matrix4x4_t *in, float x, float y, float z, float d, float *o)
Definition matrixlib.c:1717
void Matrix4x4_FromArray12FloatGL(matrix4x4_t *out, const float in[12])
Definition matrixlib.c:1352
void Matrix4x4_Transform(const matrix4x4_t *in, const float v[3], float out[3])
Definition matrixlib.c:1657
void Matrix4x4_ToArrayFloatGL(const matrix4x4_t *in, float out[16])
Definition matrixlib.c:1165
void Matrix4x4_CreateTranslate(matrix4x4_t *out, double x, double y, double z)
Definition matrixlib.c:584
void Matrix4x4_Transform3x3(const matrix4x4_t *in, const float v[3], float out[3])
Definition matrixlib.c:1685
void Matrix4x4_CreateFromQuakeEntity(matrix4x4_t *out, double x, double y, double z, double pitch, double yaw, double roll, double scale)
Definition matrixlib.c:715
int Matrix4x4_Invert_Full(matrix4x4_t *out, const matrix4x4_t *in1)
Definition matrixlib.c:145
void Matrix4x4_CreateScale3(matrix4x4_t *out, double x, double y, double z)
Definition matrixlib.c:695
void Matrix4x4_ConcatScale3(matrix4x4_t *out, double x, double y, double z)
Definition matrixlib.c:1784
void Matrix4x4_Normalize3(matrix4x4_t *out, matrix4x4_t *in1)
Definition matrixlib.c:508
void Matrix4x4_Reflect(matrix4x4_t *out, double normalx, double normaly, double normalz, double dist, double axisscale)
Definition matrixlib.c:535
void Matrix4x4_Invert_Simple(matrix4x4_t *out, const matrix4x4_t *in1)
Definition matrixlib.c:422
void Matrix4x4_ConcatTranslate(matrix4x4_t *out, double x, double y, double z)
Definition matrixlib.c:1757
double Matrix4x4_ScaleFromMatrix(const matrix4x4_t *in)
Definition matrixlib.c:1805
void Matrix4x4_FromVectors(matrix4x4_t *out, const float vx[3], const float vy[3], const float vz[3], const float t[3])
Definition matrixlib.c:970
void Matrix4x4_ToVectors(const matrix4x4_t *in, float vx[3], float vy[3], float vz[3], float t[3])
Definition matrixlib.c:939
const matrix4x4_t identitymatrix
Definition matrixlib.c:9
void Matrix4x4_ConcatRotate(matrix4x4_t *out, double angle, double x, double y, double z)
Definition matrixlib.c:1766
void Matrix4x4_OriginFromMatrix(const matrix4x4_t *in, float *out)
Definition matrixlib.c:1792
cvar_t r_shadow_realtime_dlight
Definition r_shadow.c:159
cvar_t r_shadow_realtime_world_shadows
Definition r_shadow.c:166
cvar_t r_shadow_realtime_world
Definition r_shadow.c:163
cvar_t r_shadow_gloss
Definition r_shadow.c:147
cvar_t r_shadow_realtime_dlight_shadows
Definition r_shadow.c:160
cvar_t r_shadow_realtime_world_lightmaps
Definition r_shadow.c:165
cvar_t gl_flashblend
Definition r_shadow.c:236
void R_MeshQueue_BeginScene(void)
Definition meshqueue.c:26
void R_MeshQueue_AddTransparent(dptransparentsortcategory_t category, const vec3_t center, void(*callback)(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist), const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight)
Definition meshqueue.c:33
void R_MeshQueue_RenderTransparent(void)
Definition meshqueue.c:62
#define MESHQUEUE_TRANSPARENT_BATCHSIZE
Definition meshqueue.h:6
void Mod_Skeletal_BuildTransforms(const model_t *RESTRICT model, const frameblend_t *RESTRICT frameblend, const skeleton_t *skeleton, float *RESTRICT bonepose, float *RESTRICT boneposerelative)
Definition model_alias.c:65
cvar_t r_novis
Definition model_brush.c:31
cvar_t r_trippy
Definition model_brush.c:29
#define MATERIALFLAG_ADD
Definition model_brush.h:81
#define MATERIALFLAG_SKY
Definition model_brush.h:92
#define MATERIALFLAG_VERTEXCOLOR
#define MATERIALFLAG_FULLBRIGHT
Definition model_brush.h:87
#define MATERIALFLAG_ALPHA
Definition model_brush.h:79
#define MATERIALFLAG_REFRACTION
#define MATERIALFLAG_NODRAW
Definition model_brush.h:96
#define MATERIALFLAGMASK_DEPTHSORTED
#define MATERIALFLAG_ALPHATEST
#define MATERIALFLAG_CUSTOMSURFACE
#define MATERIALFLAG_BLENDED
#define MATERIALFLAG_TRANSDEPTH
#define MATERIALFLAG_VERTEXTEXTUREBLEND
#define MATERIALFLAG_WATERALPHA
Definition model_brush.h:85
#define MATERIALFLAG_LIGHTGRID
#define MATERIALFLAG_ALPHAGEN_VERTEX
#define MATERIALFLAG_WATERSHADER
#define MATERIALFLAG_MODELLIGHT
#define MATERIALFLAG_CAMERA
#define MATERIALFLAG_OCCLUDE
#define MATERIALFLAG_NODEPTHTEST
Definition model_brush.h:83
#define MATERIALFLAGMASK_TRANSLUCENT
#define MATERIALFLAG_WALL
Definition model_brush.h:89
#define MATERIALFLAG_NOSHADOW
#define MATERIALFLAG_REFLECTION
#define MATERIALFLAG_SHORTDEPTHRANGE
#define MATERIALFLAG_NOCULLFACE
#define MATERIALFLAG_WATERSCROLL
Definition model_brush.h:94
#define MATERIALFLAG_CUSTOMBLEND
#define MATERIALFLAG_NORTLIGHT
#define Q3SURFACEFLAG_NOMARKS
msurface_t * Mod_Mesh_AddSurface(model_t *mod, texture_t *tex, qbool batchwithprevioussurface)
int Mod_Mesh_IndexForVertex(model_t *mod, msurface_t *surf, float x, float y, float z, float nx, float ny, float nz, float s, float t, float u, float v, float r, float g, float b, float a)
void Mod_BuildNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const int *elements, float *normal3f, qbool areaweighting)
cvar_t r_mipnormalmaps
texture_t * Mod_Mesh_GetTexture(model_t *mod, const char *name, int defaultdrawflags, int defaulttexflags, int defaultmaterialflags)
void Mod_Mesh_AddTriangle(model_t *mod, msurface_t *surf, int e0, int e1, int e2)
void Mod_BuildTextureVectorsFromNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const float *texcoord2f, const float *normal3f, const int *elements, float *svector3f, float *tvector3f, qbool areaweighting)
cvar_t r_mipskins
void Mod_RenderInit(void)
@ mod_brushq3
@ mod_sprite
unsigned int palette_bgra_nocolormap[256]
Definition palette.c:16
unsigned int palette_bgra_transparent[256]
Definition palette.c:24
unsigned int palette_bgra_onlyfullbrights_transparent[256]
Definition palette.c:21
unsigned int palette_bgra_nocolormapnofullbrights[256]
Definition palette.c:17
unsigned int palette_bgra_shirtaswhite[256]
Definition palette.c:23
unsigned int palette_bgra_complete[256]
Definition palette.c:13
unsigned int palette_bgra_nofullbrights_transparent[256]
Definition palette.c:19
unsigned char palette_featureflags[256]
Definition palette.c:26
unsigned int palette_bgra_nofullbrights[256]
Definition palette.c:18
unsigned int palette_bgra_onlyfullbrights[256]
Definition palette.c:20
unsigned int palette_bgra_pantsaswhite[256]
Definition palette.c:22
#define PALETTEFEATURE_SHIRT
Definition palette.h:8
#define PALETTEFEATURE_GLOW
Definition palette.h:9
#define PALETTEFEATURE_PANTS
Definition palette.h:7
int PolygonF_Clip(int innumpoints, const float *inpoints, float planenormalx, float planenormaly, float planenormalz, float planedist, float epsilon, int outfrontmaxpoints, float *outfrontpoints)
Definition polygon.c:99
void PolygonD_QuadForPlane(double *outpoints, double planenormalx, double planenormaly, double planenormalz, double planedist, double quadsize)
Definition polygon.c:54
void PolygonD_Divide(int innumpoints, const double *inpoints, double planenormalx, double planenormaly, double planenormalz, double planedist, double epsilon, int outfrontmaxpoints, double *outfrontpoints, int *neededfrontpoints, int outbackmaxpoints, double *outbackpoints, int *neededbackpoints, int *oncountpointer)
Definition polygon.c:245
#define CLVM_prog
Definition progsvm.h:766
#define PRVM_serveredictedict(ed, fieldname)
Definition progsvm.h:174
#define PRVM_gameedictedict(ed, fieldname)
Definition progsvm.h:162
#define PRVM_EDICT_NUM(n)
Definition progsvm.h:866
#define PRVM_serveredictfloat(ed, fieldname)
Definition progsvm.h:171
#define SVVM_prog
Definition progsvm.h:765
#define RENDER_EXTERIORMODEL
Definition protocol.h:359
#define RENDER_VIEWMODEL
Definition protocol.h:358
#define RENDER_DYNAMICMODELLIGHT
Definition protocol.h:373
#define RENDER_WORLDOBJECT
Definition protocol.h:362
#define RENDER_DOUBLESIDED
Definition protocol.h:371
#define RENDER_ADDITIVE
Definition protocol.h:370
#define RENDER_NOSELFSHADOW
Definition protocol.h:367
#define RENDER_LIGHT
Definition protocol.h:366
#define RENDER_CUSTOMIZEDMODELLIGHT
Definition protocol.h:372
#define RENDER_NODEPTHTEST
Definition protocol.h:369
int i
#define MAX_WATERPLANES
max number of water planes visible (each one causes additional view renders)
Definition qdefs.h:129
#define MAX_EDICTS
max number of objects in game world at once (32768 protocol limit)
Definition qdefs.h:105
#define MAX_CUBEMAPS
max number of cubemap textures loaded for light filters
Definition qdefs.h:130
#define MAX_QPATH
max length of a quake game pathname
Definition qdefs.h:169
#define MAX_OCCLUSION_QUERIES
max number of query objects that can be used in one frame
Definition qdefs.h:124
#define MAX_DECALSYSTEM_QUEUE
Definition qdefs.h:150
#define NULL
Definition qtypes.h:12
float vec_t
Definition qtypes.h:64
vec_t vec3_t[3]
Definition qtypes.h:67
bool qbool
Definition qtypes.h:9
vec_t vec4_t[4]
Definition qtypes.h:68
cvar_t chase_active
Definition view.c:132
void R_DrawExplosions(void)
void R_Explosion_Init(void)
void R_LightningBeams_Init(void)
Definition r_lightning.c:96
void R_RegisterModule(const char *name, void(*start)(void), void(*shutdown)(void), void(*newmap)(void), void(*devicelost)(void), void(*devicerestored)(void))
Definition r_modules.c:25
int q3wavefunc_t
Definition r_qshader.h:41
#define Q3MAXTCMODS
Definition r_qshader.h:26
#define Q3MAXDEFORMS
Definition r_qshader.h:27
#define Q3WAVEFUNC_USER_COUNT
Definition r_qshader.h:42
@ Q3DEFORM_NORMAL
Definition r_qshader.h:61
@ Q3DEFORM_TEXT3
Definition r_qshader.h:54
@ Q3DEFORM_TEXT5
Definition r_qshader.h:56
@ Q3DEFORM_TEXT0
Definition r_qshader.h:51
@ Q3DEFORM_AUTOSPRITE
Definition r_qshader.h:49
@ Q3DEFORM_PROJECTIONSHADOW
Definition r_qshader.h:48
@ Q3DEFORM_WAVE
Definition r_qshader.h:60
@ Q3DEFORM_TEXT1
Definition r_qshader.h:52
@ Q3DEFORM_TEXT2
Definition r_qshader.h:53
@ Q3DEFORM_NONE
Definition r_qshader.h:47
@ Q3DEFORM_AUTOSPRITE2
Definition r_qshader.h:50
@ Q3DEFORM_TEXT7
Definition r_qshader.h:58
@ Q3DEFORM_MOVE
Definition r_qshader.h:62
@ Q3DEFORM_TEXT6
Definition r_qshader.h:57
@ Q3DEFORM_TEXT4
Definition r_qshader.h:55
@ Q3DEFORM_BULGE
Definition r_qshader.h:59
@ TRANSPARENTSORT_DISTANCE
Definition r_qshader.h:194
@ TRANSPARENTSORT_SKY
Definition r_qshader.h:193
@ TRANSPARENTSORT_HUD
Definition r_qshader.h:195
#define Q3WAVEFUNC_USER_SHIFT
Definition r_qshader.h:43
@ Q3TCMOD_SCALE
Definition r_qshader.h:114
@ Q3TCMOD_ROTATE
Definition r_qshader.h:113
@ Q3TCMOD_ENTITYTRANSLATE
Definition r_qshader.h:112
@ Q3TCMOD_TRANSFORM
Definition r_qshader.h:117
@ Q3TCMOD_SCROLL
Definition r_qshader.h:115
@ Q3TCMOD_PAGE
Definition r_qshader.h:119
@ Q3TCMOD_TURBULENT
Definition r_qshader.h:118
@ Q3TCMOD_STRETCH
Definition r_qshader.h:116
@ Q3TCMOD_NONE
Definition r_qshader.h:111
@ Q3TCMOD_COUNT
Definition r_qshader.h:120
@ OFFSETMAPPING_DEFAULT
Definition r_qshader.h:186
@ OFFSETMAPPING_OFF
Definition r_qshader.h:185
@ OFFSETMAPPING_LINEAR
Definition r_qshader.h:187
@ OFFSETMAPPING_RELIEF
Definition r_qshader.h:188
@ Q3TCGEN_VECTOR
Definition r_qshader.h:104
@ Q3TCGEN_ENVIRONMENT
Definition r_qshader.h:102
@ Q3TCGEN_LIGHTMAP
Definition r_qshader.h:103
@ Q3TCGEN_TEXTURE
Definition r_qshader.h:101
@ Q3WAVEFUNC_INVERSESAWTOOTH
Definition r_qshader.h:32
@ Q3WAVEFUNC_SAWTOOTH
Definition r_qshader.h:34
@ Q3WAVEFUNC_TRIANGLE
Definition r_qshader.h:37
@ Q3WAVEFUNC_NOISE
Definition r_qshader.h:33
@ Q3WAVEFUNC_COUNT
Definition r_qshader.h:38
@ Q3WAVEFUNC_NONE
Definition r_qshader.h:31
@ Q3WAVEFUNC_SIN
Definition r_qshader.h:35
@ Q3WAVEFUNC_SQUARE
Definition r_qshader.h:36
cvar_t r_shadow_glossintensity
Definition r_shadow.c:149
int r_shadow_viewx
Definition r_shadow.c:127
cvar_t r_shadow_bumpscale_bumpmap
Definition r_shadow.c:142
float r_shadow_modelshadowmap_parameters[4]
Definition r_shadow.c:43
rtexture_t * r_shadow_prepassgeometrynormalmaptexture
Definition r_shadow.c:120
void R_Shadow_DrawShadowMaps(void)
Definition r_shadow.c:4212
qbool r_shadow_shadowmapvsdct
Definition r_shadow.c:57
rtexture_t * r_shadow_viewdepthtexture
Definition r_shadow.c:125
int r_shadow_viewfbo
Definition r_shadow.c:124
rtexture_t * r_shadow_attenuationgradienttexture
Definition r_shadow.c:108
void R_Shadow_PrepareLights(void)
Definition r_shadow.c:4039
qbool R_Shadow_ShadowMappingEnabled(void)
Definition r_shadow.c:378
float r_shadow_lightshadowmap_parameters[4]
Definition r_shadow.c:41
void R_Shadow_PrepareModelShadows(void)
Definition r_shadow.c:4255
qbool r_shadow_usingshadowmap2d
Definition r_shadow.c:37
cvar_t r_shadow_glossexact
Definition r_shadow.c:152
float r_shadow_lightshadowmap_texturescale[4]
Definition r_shadow.c:40
rtexture_t * r_shadow_viewcolortexture
Definition r_shadow.c:126
int r_shadow_viewy
Definition r_shadow.c:128
qbool r_shadow_usingshadowmaportho
Definition r_shadow.c:38
cvar_t r_shadow_frontsidecasting
Definition r_shadow.c:158
void R_Shadow_UpdateBounceGridTexture(void)
Definition r_shadow.c:2755
rtexture_t * r_shadow_shadowmapvsdcttexture
Definition r_shadow.c:112
rtexture_t * r_shadow_shadowmap2ddepthtexture
Definition r_shadow.c:111
matrix4x4_t r_shadow_shadowmapmatrix
Definition r_shadow.c:62
void R_Shadow_DrawCoronas(void)
Definition r_shadow.c:4541
void R_Shadow_Init(void)
Definition r_shadow.c:601
cvar_t r_shadow_gloss2intensity
Definition r_shadow.c:148
rtexture_t * r_shadow_shadowmap2ddepthbuffer
Definition r_shadow.c:110
void R_Shadow_DrawLights(void)
Definition r_shadow.c:4239
cvar_t r_shadow_glossexponent
Definition r_shadow.c:150
cvar_t r_shadow_gloss2exponent
Definition r_shadow.c:151
void R_Shadow_DrawPrepass(void)
Definition r_shadow.c:3966
void R_Shadow_UpdateWorldLightSelection(void)
Definition r_shadow.c:5302
int r_shadow_viewwidth
Definition r_shadow.c:129
cvar_t r_shadow_bumpscale_basetexture
Definition r_shadow.c:141
int r_shadow_viewheight
Definition r_shadow.c:130
r_shadow_bouncegrid_state_t r_shadow_bouncegrid_state
Definition r_shadow.c:259
void R_CompleteLightPoint(float *ambient, float *diffuse, float *lightdir, const vec3_t p, const int flags, float lightmapintensity, float ambientintensity)
Definition r_shadow.c:6027
float r_shadow_modelshadowmap_texturescale[4]
Definition r_shadow.c:42
#define LP_DYNLIGHT
Definition r_shadow.h:194
#define LP_LIGHTMAP
Definition r_shadow.h:192
#define LP_RTWORLD
Definition r_shadow.h:193
cvar_t r_sky_scissor
Definition r_sky.c:9
int skyrendermasked
Definition r_sky.c:11
void R_Sky_Init(void)
Definition r_sky.c:464
int skyrenderlater
Definition r_sky.c:10
void R_Sky(void)
Definition r_sky.c:403
int skyscissor[4]
Definition r_sky.c:12
void R_SkyStartFrame(void)
Definition r_sky.c:57
int r_timereport_active
Definition r_stats.c:189
void R_TimeReport(const char *desc)
Definition r_stats.c:193
@ r_stat_animcache_shape_count
Definition r_stats.h:67
@ r_stat_batch_fast_vertices
Definition r_stats.h:77
@ r_stat_batch_dynamic_triangles_because_deformvertexes_normal
Definition r_stats.h:110
@ r_stat_batch_entitycustom_surfaces
Definition r_stats.h:164
@ r_stat_batch_dynamic_vertices_because_deformvertexes_move
Definition r_stats.h:121
@ r_stat_batch_dynamic_surfaces_because_deformvertexes_wave
Definition r_stats.h:112
@ r_stat_batch_dynamic_batches_because_deformvertexes_autosprite
Definition r_stats.h:99
@ r_stat_batch_dynamic_surfaces_because_deformvertexes_move
Definition r_stats.h:120
@ r_stat_batch_dynamic_vertices_because_deformvertexes_normal
Definition r_stats.h:109
@ r_stat_batch_entityanimate_count
Definition r_stats.h:151
@ r_stat_framedatacurrent
Definition r_stats.h:51
@ r_stat_batch_dynamic_vertices_because_nogaps
Definition r_stats.h:141
@ r_stat_batch_dynamic_vertices_because_cvar
Definition r_stats.h:93
@ r_stat_batch_entitycache_triangles
Definition r_stats.h:150
@ r_stat_batch_dynamic_batches_because_deformvertexes_bulge
Definition r_stats.h:115
@ r_stat_batch_dynamic_batches_because_tcmod_turbulent
Definition r_stats.h:135
@ r_stat_batch_entityskeletal_vertices
Definition r_stats.h:157
@ r_stat_batch_dynamic_batches
Definition r_stats.h:83
@ r_stat_batch_dynamic_vertices_because_tcgen_lightmap
Definition r_stats.h:125
@ r_stat_batch_dynamic_surfaces_because_tcgen_environment
Definition r_stats.h:132
@ r_stat_batch_entitycustom_triangles
Definition r_stats.h:166
@ r_stat_drawndecals
Definition r_stats.h:22
@ r_stat_animcache_skeletal_bones
Definition r_stats.h:62
@ r_stat_batch_vertices
Definition r_stats.h:73
@ r_stat_batch_dynamic_batches_because_deformvertexes_move
Definition r_stats.h:119
@ r_stat_rendertargets_used
Definition r_stats.h:45
@ r_stat_batch_entitystatic_surfaces
Definition r_stats.h:160
@ r_stat_batch_copytriangles_vertices
Definition r_stats.h:81
@ r_stat_bloom
Definition r_stats.h:42
@ r_stat_batch_dynamic_vertices_because_deformvertexes_wave
Definition r_stats.h:113
@ r_stat_rendertargets_pixels
Definition r_stats.h:46
@ r_stat_renders
Definition r_stats.h:11
@ r_stat_batch_dynamic_triangles_because_cvar
Definition r_stats.h:94
@ r_stat_batch_dynamic_vertices_because_tcgen_environment
Definition r_stats.h:133
@ r_stat_batch_dynamic_batches_because_cvar
Definition r_stats.h:91
@ r_stat_batch_dynamic_batches_because_deformvertexes_wave
Definition r_stats.h:111
@ r_stat_batch_dynamic_triangles_because_deformvertexes_wave
Definition r_stats.h:114
@ r_stat_batch_dynamic_batches_because_lightmapvertex
Definition r_stats.h:95
@ r_stat_batch_dynamic_surfaces_because_deformvertexes_normal
Definition r_stats.h:108
@ r_stat_batch_copytriangles_batches
Definition r_stats.h:79
@ r_stat_entities_triangles
Definition r_stats.h:14
@ r_stat_animcache_shape_maxvertices
Definition r_stats.h:69
@ r_stat_bufferdatasize_vertex
Definition r_stats.h:57
@ r_stat_batch_dynamic_surfaces_because_tcgen_vector
Definition r_stats.h:128
@ r_stat_bloom_drawpixels
Definition r_stats.h:44
@ r_stat_batch_dynamic_surfaces_because_deformvertexes_autosprite2
Definition r_stats.h:104
@ r_stat_batch_dynamic_vertices
Definition r_stats.h:85
@ r_stat_batch_dynamic_triangles_because_deformvertexes_bulge
Definition r_stats.h:118
@ r_stat_batch_dynamic_triangles
Definition r_stats.h:86
@ r_stat_batch_entitycache_vertices
Definition r_stats.h:149
@ r_stat_batch_dynamic_surfaces_because_nogaps
Definition r_stats.h:140
@ r_stat_batch_entitycustom_vertices
Definition r_stats.h:165
@ r_stat_batch_dynamic_vertices_because_tcgen_vector
Definition r_stats.h:129
@ r_stat_batch_entitycache_surfaces
Definition r_stats.h:148
@ r_stat_batch_triangles
Definition r_stats.h:74
@ r_stat_batch_entityanimate_surfaces
Definition r_stats.h:152
@ r_stat_batch_dynamic_surfaces_because_deformvertexes_autosprite
Definition r_stats.h:100
@ r_stat_batch_dynamicskeletal_triangles
Definition r_stats.h:90
@ r_stat_batch_dynamicskeletal_batches
Definition r_stats.h:87
@ r_stat_batch_entitycustom_count
Definition r_stats.h:163
@ r_stat_batch_dynamic_surfaces_because_tcgen_lightmap
Definition r_stats.h:124
@ r_stat_batch_surfaces
Definition r_stats.h:72
@ r_stat_batch_dynamicskeletal_vertices
Definition r_stats.h:89
@ r_stat_animcache_skeletal_maxbones
Definition r_stats.h:63
@ r_stat_batch_dynamic_batches_because_nogaps
Definition r_stats.h:139
@ r_stat_entities_surfaces
Definition r_stats.h:13
@ r_stat_batch_copytriangles_surfaces
Definition r_stats.h:80
@ r_stat_batch_fast_surfaces
Definition r_stats.h:76
@ r_stat_batch_dynamic_batches_because_tcgen_environment
Definition r_stats.h:131
@ r_stat_batch_dynamic_triangles_because_deformvertexes_autosprite2
Definition r_stats.h:106
@ r_stat_batch_dynamic_surfaces_because_tcmod_turbulent
Definition r_stats.h:136
@ r_stat_animcache_skeletal_count
Definition r_stats.h:61
@ r_stat_batch_dynamic_batches_because_deformvertexes_normal
Definition r_stats.h:107
@ r_stat_batch_dynamic_surfaces_because_cvar
Definition r_stats.h:92
@ r_stat_batch_entitystatic_triangles
Definition r_stats.h:162
@ r_stat_batch_dynamic_batches_because_deformvertexes_autosprite2
Definition r_stats.h:103
@ r_stat_framedatasize
Definition r_stats.h:52
@ r_stat_batch_dynamic_vertices_because_deformvertexes_bulge
Definition r_stats.h:117
@ r_stat_batch_dynamic_triangles_because_tcgen_environment
Definition r_stats.h:134
@ r_stat_batch_fast_triangles
Definition r_stats.h:78
@ r_stat_animcache_shade_count
Definition r_stats.h:64
@ r_stat_batch_entitystatic_count
Definition r_stats.h:159
@ r_stat_batch_dynamic_batches_because_tcgen_vector
Definition r_stats.h:127
@ r_stat_batch_dynamic_triangles_because_lightmapvertex
Definition r_stats.h:98
@ r_stat_batch_dynamic_triangles_because_nogaps
Definition r_stats.h:142
@ r_stat_batch_dynamic_triangles_because_deformvertexes_autosprite
Definition r_stats.h:102
@ r_stat_batch_dynamic_surfaces_because_deformvertexes_bulge
Definition r_stats.h:116
@ r_stat_batch_entityskeletal_surfaces
Definition r_stats.h:156
@ r_stat_batch_copytriangles_triangles
Definition r_stats.h:82
@ r_stat_batch_fast_batches
Definition r_stats.h:75
@ r_stat_batch_dynamicskeletal_surfaces
Definition r_stats.h:88
@ r_stat_totaldecals
Definition r_stats.h:23
@ r_stat_batch_dynamic_vertices_because_lightmapvertex
Definition r_stats.h:97
@ r_stat_bloom_copypixels
Definition r_stats.h:43
@ r_stat_batch_dynamic_vertices_because_deformvertexes_autosprite2
Definition r_stats.h:105
@ r_stat_batch_dynamic_batches_because_tcgen_lightmap
Definition r_stats.h:123
@ r_stat_batch_dynamic_surfaces_because_lightmapvertex
Definition r_stats.h:96
@ r_stat_batch_entitystatic_vertices
Definition r_stats.h:161
@ r_stat_batch_dynamic_vertices_because_deformvertexes_autosprite
Definition r_stats.h:101
@ r_stat_batch_withgaps
Definition r_stats.h:71
@ r_stat_batch_entityanimate_vertices
Definition r_stats.h:153
@ r_stat_animcache_shape_vertices
Definition r_stats.h:68
@ r_stat_batch_dynamic_vertices_because_tcmod_turbulent
Definition r_stats.h:137
@ r_stat_entities
Definition r_stats.h:12
@ r_stat_batch_entitycache_count
Definition r_stats.h:147
@ r_stat_animcache_shade_vertices
Definition r_stats.h:65
@ r_stat_batch_entityskeletal_triangles
Definition r_stats.h:158
@ r_stat_batch_dynamic_triangles_because_tcgen_vector
Definition r_stats.h:130
@ r_stat_animcache_shade_maxvertices
Definition r_stats.h:66
@ r_stat_batch_dynamic_triangles_because_tcmod_turbulent
Definition r_stats.h:138
@ r_stat_batch_batches
Definition r_stats.h:70
@ r_stat_bufferdatacurrent_vertex
Definition r_stats.h:53
@ r_stat_batch_entityskeletal_count
Definition r_stats.h:155
@ r_stat_batch_entityanimate_triangles
Definition r_stats.h:154
@ r_stat_batch_dynamic_surfaces
Definition r_stats.h:84
@ r_stat_batch_dynamic_triangles_because_deformvertexes_move
Definition r_stats.h:122
@ r_stat_batch_dynamic_triangles_because_tcgen_lightmap
Definition r_stats.h:126
#define TEXF_PICMIP
Definition r_textures.h:21
#define TEXF_IMPORTANTBITS
Definition r_textures.h:39
#define TEXF_ALPHA
Definition r_textures.h:9
#define TEXF_FORCELINEAR
Definition r_textures.h:19
#define TEXF_MIPMAP
Definition r_textures.h:11
#define TEXF_FORCENEAREST
Definition r_textures.h:17
#define TEXF_COMPRESS
Definition r_textures.h:23
textype_t
Definition r_textures.h:44
@ TEXTYPE_PALETTE
Definition r_textures.h:49
@ TEXTYPE_SRGB_BGRA
Definition r_textures.h:73
@ TEXTYPE_COLORBUFFER
Definition r_textures.h:84
@ TEXTYPE_SRGB_PALETTE
Definition r_textures.h:69
@ TEXTYPE_COLORBUFFER32F
Definition r_textures.h:88
@ TEXTYPE_UNUSED
Definition r_textures.h:46
@ TEXTYPE_BGRA
Definition r_textures.h:53
@ TEXTYPE_DEPTHBUFFER24STENCIL8
Definition r_textures.h:94
@ TEXTYPE_COLORBUFFER16F
Definition r_textures.h:86
#define TEXF_CLAMP
Definition r_textures.h:15
#define TEXF_FORCE_RELOAD
Definition r_textures.h:41
#define TEXF_PERSISTENT
Definition r_textures.h:25
#define TEXF_RENDERTARGET
Definition r_textures.h:37
r_bufferdata_type_t
enum of the various types of hardware buffer object used in rendering note that the r_buffermegs[] ar...
Definition render.h:527
@ R_BUFFERDATA_VERTEX
Definition render.h:528
@ R_BUFFERDATA_COUNT
uniform buffer
Definition render.h:532
@ R_BUFFERDATA_UNIFORM
index buffer - 32bit (because D3D cares)
Definition render.h:531
@ R_BUFFERDATA_INDEX32
index buffer - 16bit (because D3D cares)
Definition render.h:530
@ R_BUFFERDATA_INDEX16
vertex buffer
Definition render.h:529
#define SHADERPERMUTATION_FOGALPHAHACK
fog color and density determined by texture mapped on vertical axis
Definition render.h:81
#define SHADERPERMUTATION_SKELETAL
(skeletal models) use skeletal matrices to deform vertices (gpu-skinning)
Definition render.h:103
#define SHADERPERMUTATION_SPECULAR
(lightsource or deluxemapping) render specular effects
Definition render.h:86
#define SHADERPERMUTATION_POSTPROCESSING
user defined postprocessing (postprocessing only)
Definition render.h:87
#define SHADERPERMUTATION_COUNT
size of shaderpermutationinfo array
Definition render.h:105
#define SHADERPERMUTATION_BLOOM
bloom (postprocessing only)
Definition render.h:85
@ SHADERMODE_DEFERREDGEOMETRY
(deferred) render material properties to screenspace geometry buffers
Definition render.h:67
@ SHADERMODE_FLATCOLOR
(lightmap) modulate texture by uniform color (q1bsp, q3bsp)
Definition render.h:55
@ SHADERMODE_LIGHTDIRECTION
(lightmap) use directional pixel shading from fixed light direction (q3bsp)
Definition render.h:63
@ SHADERMODE_VERTEXCOLOR
(lightmap) modulate texture by vertex colors (q3bsp)
Definition render.h:56
@ SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE
(lightmap) use directional pixel shading from texture containing modelspace light directions (q3bsp d...
Definition render.h:58
@ SHADERMODE_COUNT
Definition render.h:69
@ SHADERMODE_LIGHTMAP
(lightmap) modulate texture by lightmap texture (q1bsp, q3bsp)
Definition render.h:57
@ SHADERMODE_LIGHTDIRECTIONMAP_FORCED_LIGHTMAP
Definition render.h:60
@ SHADERMODE_GENERIC
(particles/HUD/etc) vertex color, optionally multiplied by one texture
Definition render.h:52
@ SHADERMODE_POSTPROCESS
postprocessing shader (r_glsl_postprocess)
Definition render.h:53
@ SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE
(lightmap) use directional pixel shading from texture containing tangentspace light directions (q1bsp...
Definition render.h:59
@ SHADERMODE_DEFERREDLIGHTSOURCE
(deferred) use directional pixel shading from light source (rtlight) on screenspace geometry buffers
Definition render.h:68
@ SHADERMODE_WATER
refract background and reflection (the material is rendered normally after this pass)
Definition render.h:66
@ SHADERMODE_DEPTH_OR_SHADOW
(depthfirst/shadows) vertex shader only
Definition render.h:54
@ SHADERMODE_LIGHTSOURCE
(lightsource) use directional pixel shading from light source (rtlight)
Definition render.h:64
@ SHADERMODE_LIGHTGRID
(lightmap) use directional pixel shading from lightgrid data (q3bsp)
Definition render.h:62
@ SHADERMODE_LIGHTDIRECTIONMAP_FORCED_VERTEXCOLOR
Definition render.h:61
@ SHADERMODE_REFRACTION
refract background (the material is rendered normally after this pass)
Definition render.h:65
#define SHADERPERMUTATION_ALPHAKILL
(deferredgeometry) discard pixel if diffuse texture alpha below 0.5, (generic) apply global alpha
Definition render.h:95
#define SHADERPERMUTATION_ALPHAGEN_VERTEX
alphaGen vertex
Definition render.h:102
#define FOGMASKTABLEWIDTH
Definition render.h:431
#define SHADERPERMUTATION_DEPTHRGB
read/write depth values in RGB color coded format for older hardware without depth samplers
Definition render.h:101
#define SHADERPERMUTATION_GLOW
(lightmap) blend in an additive glow texture
Definition render.h:84
#define SHADERPERMUTATION_FOGHEIGHTTEXTURE
fog color and density determined by texture mapped on vertical axis
Definition render.h:80
#define SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL
(lightmap) use 16-component pixels in bouncegrid texture for directional lighting rather than standar...
Definition render.h:99
#define SHADERPERMUTATION_FOGOUTSIDE
tint the color by fog color or black if using additive blend mode
Definition render.h:79
#define BATCHNEED_ALLOWMULTIDRAW
Definition render.h:798
#define SHADERPERMUTATION_SHADOWMAPVSDCT
(lightsource) use virtual shadow depth cube texture for shadowmap indexing
Definition render.h:92
void Sbar_Init(void)
Definition sbar.c:359
#define BATCHNEED_NOGAPS
Definition render.h:796
#define SHADERPERMUTATION_VIEWTINT
view tint (postprocessing only), use vertex colors (generic only)
Definition render.h:75
#define BATCHNEED_ARRAY_VERTEXCOLOR
Definition render.h:792
#define BATCHNEED_ARRAY_NORMAL
Definition render.h:789
#define BATCHNEED_ALWAYSCOPY
Definition render.h:797
#define SHADERPERMUTATION_OCCLUDE
use occlusion buffer for corona
Definition render.h:104
#define BATCHNEED_ARRAY_SKELETAL
Definition render.h:795
#define BATCHNEED_ARRAY_LIGHTMAP
Definition render.h:794
#define SHADERPERMUTATION_OFFSETMAPPING
adjust texcoords to roughly simulate a displacement mapped surface
Definition render.h:89
@ SHADERLANGUAGE_COUNT
Definition render.h:45
@ SHADERLANGUAGE_GLSL
Definition render.h:44
#define SHADERPERMUTATION_SHADOWMAP2D
(lightsource) use shadowmap texture as light filter
Definition render.h:91
#define SHADERPERMUTATION_BOUNCEGRID
(lightmap) use Texture_BounceGrid as an additional source of ambient light
Definition render.h:98
#define SHADERPERMUTATION_VERTEXTEXTUREBLEND
indicates this is a two-layer material blend based on vertex alpha (q3bsp)
Definition render.h:74
#define BATCHNEED_ARRAY_VECTOR
Definition render.h:790
#define SHADERPERMUTATION_FOGINSIDE
tint the color by fog color or black if using additive blend mode
Definition render.h:78
#define SHADERPERMUTATION_NORMALMAPSCROLLBLEND
(water) counter-direction normalmaps scrolling
Definition render.h:97
#define SHADERPERMUTATION_SHADOWMAPORTHO
(lightsource) use orthographic shadowmap projection
Definition render.h:93
#define BATCHNEED_ARRAY_VERTEX
Definition render.h:788
#define SHADERPERMUTATION_CUBEFILTER
(lightsource) use cubemap light filter
Definition render.h:83
#define SHADERPERMUTATION_REFLECTION
normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the su...
Definition render.h:88
r_refdef_scene_type_t
Definition render.h:222
@ RST_CLIENT
Definition render.h:223
@ RST_COUNT
Definition render.h:225
rsurfacepass_t
Definition render.h:806
@ RSURFPASS_BACKGROUND
Definition render.h:808
@ RSURFPASS_BASE
Definition render.h:807
@ RSURFPASS_DEFERREDGEOMETRY
Definition render.h:810
@ RSURFPASS_RTLIGHT
Definition render.h:809
#define SHADERPERMUTATION_REFLECTCUBE
fake reflections using global cubemap (not HDRI light probe)
Definition render.h:96
#define SHADERPERMUTATION_SATURATION
saturation (postprocessing only)
Definition render.h:77
#define SHADERPERMUTATION_DEFERREDLIGHTMAP
(lightmap) read Texture_ScreenDiffuse/Specular textures and add them on top of lightmapping
Definition render.h:94
#define SHADERPERMUTATION_COLORMAPPING
indicates this is a colormapped skin
Definition render.h:76
#define SHADERPERMUTATION_GAMMARAMPS
gamma (postprocessing only)
Definition render.h:82
#define SHADERPERMUTATION_TRIPPY
use trippy vertex shader effect
Definition render.h:100
#define BATCHNEED_ARRAY_TEXCOORD
Definition render.h:793
#define SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING
adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also...
Definition render.h:90
#define SHADERPERMUTATION_DIFFUSE
(lightsource) whether to use directional shading
Definition render.h:73
server_t sv
local server
Definition sv_main.c:220
#define SOLID_BBOX
touch on edge, block
Definition server.h:334
#define SOLID_SLIDEBOX
touch on edge, but not an onground
Definition server.h:335
#define SOLID_CORPSE
same as SOLID_BBOX, except it behaves as SOLID_NOT against SOLID_SLIDEBOX objects (players/monsters)
Definition server.h:338
#define SOLID_NOT
no interaction with other objects
Definition server.h:332
#define SOLID_TRIGGER
touch on edge, but not blocking
Definition server.h:333
#define SOLID_BSP
bsp clip, touch on edge, block
Definition server.h:336
dp_FragColor r
vec3 y1
vec3 color
precision highp float
Definition shader_glsl.h:45
uniform highp float FogHeightFade
vec2 dir
dp_FragColor g
float f
vec3 y2
vec3 x2
vec3 normal
float fogfrac
dp_FragColor b
vec3 x1
vec4 sw
vec3 float FogPlaneVertexDist
void vec2 tc
ret a
uniform highp float FogPlaneViewDist
void S_ExtraUpdate(void)
Definition snd_main.c:2236
float intensity
Definition snd_mix.c:326
#define SPR_LABEL
Definition spritegn.h:101
#define SPR_LABEL_SCALE
Definition spritegn.h:102
float framerate
Definition bih.h:66
int numleafs
Definition bih.h:69
vec3_t movement_origin
Definition client.h:810
double oldtime
Definition client.h:869
vec3_t movement_velocity
Definition client.h:811
cl_locnode_t * locnodes
Definition client.h:1126
unsigned int decalsequence
Definition client.h:979
scoreboard_t * scores
Definition client.h:946
cshift_t cshifts[NUM_CSHIFTS]
Definition client.h:776
vec3_t viewangles
Definition client.h:787
struct model_s * worldmodel
Definition client.h:935
double realframetime
Definition client.h:872
double time
Definition client.h:869
float motionbluralpha
Definition client.h:883
csqc_vidvars_t csqc_vidvars
Definition client.h:835
char worldnamenoextension[MAX_QPATH]
Definition client.h:901
qbool demoplayback
Definition client.h:588
cactive_t state
Definition client.h:569
mempool_t * levelmempool
Definition client.h:572
protocolversion_t protocol
Definition client.h:618
command interpreter state - the tokenizing and execution of commands, as well as pointers to which cv...
Definition cmd.h:127
float percent
Definition client.h:508
qbool drawworld
Definition client.h:707
rtexture_t * texture
Definition gl_rmain.c:290
Definition cvar.h:66
float value
Definition cvar.h:74
int integer
Definition cvar.h:73
const char * string
Definition cvar.h:71
int freedecal
Definition client.h:60
model_t * model
Definition client.h:57
int maxdecals
Definition client.h:59
int * element3i
Definition client.h:66
tridecal_t * decals
Definition client.h:62
double lastupdatetime
Definition client.h:58
int numdecals
Definition client.h:61
unsigned short * element3s
Definition client.h:67
float * color4f
Definition client.h:65
float * texcoord2f
Definition client.h:64
float * vertex3f
Definition client.h:63
frameblend_t frameblend[MAX_FRAMEBLENDS]
Definition client.h:374
float render_fullbright[3]
Definition client.h:413
vec_t userwavefunc_param[Q3WAVEFUNC_USER_COUNT]
Definition client.h:446
float * animcache_skeletaltransform3x4
Definition client.h:396
float render_rtlight_diffuse[3]
Definition client.h:427
matrix4x4_t inversematrix
Definition client.h:335
float render_glowmod[3]
Definition client.h:415
r_meshbuffer_t * animcache_vertex3f_vertexbuffer
Definition client.h:381
matrix4x4_t matrix
Definition client.h:333
float render_modellight_specular[3]
Definition client.h:421
float * animcache_normal3f
Definition client.h:383
float colormod[3]
Definition client.h:360
vec3_t mins
Definition client.h:372
int animcache_skeletaltransform3x4size
Definition client.h:399
qbool render_rtlight_disabled
Definition client.h:432
int animcache_vertex3f_bufferoffset
Definition client.h:382
r_meshbuffer_t * animcache_svector3f_vertexbuffer
Definition client.h:387
float render_modellight_lightdir_world[3]
Definition client.h:419
model_t * model
Definition client.h:344
float render_lightmap_ambient[3]
Definition client.h:423
decalsystem_t decalsystem
Definition client.h:439
float render_modellight_lightdir_local[3]
Definition client.h:420
vec3_t colormap_shirtcolor
Definition client.h:349
r_meshbuffer_t * animcache_tvector3f_vertexbuffer
Definition client.h:390
qbool render_modellight_forced
Definition client.h:430
float transparent_offset
Definition client.h:341
framegroupblend_t framegroupblend[MAX_FRAMEGROUPBLENDS]
Definition client.h:364
double last_trace_visibility
Definition client.h:443
double shadertime
Definition client.h:367
float * animcache_vertex3f
Definition client.h:380
float render_lightmap_diffuse[3]
Definition client.h:424
int animcache_svector3f_bufferoffset
Definition client.h:388
float render_modellight_ambient[3]
Definition client.h:417
float render_rtlight_specular[3]
Definition client.h:428
float render_lightmap_specular[3]
Definition client.h:425
r_meshbuffer_t * animcache_skeletaltransform3x4buffer
Definition client.h:397
r_meshbuffer_t * animcache_normal3f_vertexbuffer
Definition client.h:384
qbool render_lightgrid
Definition client.h:434
float render_modellight_diffuse[3]
Definition client.h:418
float glowmod[3]
Definition client.h:361
float * animcache_svector3f
Definition client.h:386
int animcache_tvector3f_bufferoffset
Definition client.h:391
float * animcache_tvector3f
Definition client.h:389
vec3_t colormap_pantscolor
Definition client.h:348
int animcache_skeletaltransform3x4offset
Definition client.h:398
vec3_t maxs
Definition client.h:372
skeleton_t * skeleton
Definition client.h:376
int animcache_normal3f_bufferoffset
Definition client.h:385
entity_render_t render
Definition client.h:478
float lerp
Definition client.h:314
double realtime
Definition host.h:37
int clusterindex
int(* BoxTouchingVisibleLeafs)(struct model_s *model, const unsigned char *visibleleafs, const vec3_t mins, const vec3_t maxs)
struct q3mbrush_s * data_brushes
qbool(* TraceLineOfSight)(struct model_s *model, const vec3_t start, const vec3_t end, const vec3_t acceptmins, const vec3_t acceptmaxs)
qbool supportwateralpha
size_t(* FatPVS)(struct model_s *model, const vec3_t org, vec_t radius, unsigned char **pvsbuffer, mempool_t *pool, qbool merge)
mleaf_t *(* PointInLeaf)(struct model_s *model, const vec3_t p)
int * data_collisionelement3i
int num_pvsclusterbytes
float * data_collisionvertex3f
mleaf_t * data_leafs
model_brush_lightstyleinfo_t * data_lightstyleinfo
Definition model_q1bsp.h:37
unsigned char * lightmapupdateflags
Definition model_q1bsp.h:40
matrix4x4_t lightgridworldtotexturematrix
qbool deluxemapping_modelspace
rtexture_t * lightgridtexture
model_brush_t brush
void(* AnimateVertices)(const struct model_s *RESTRICT model, const struct frameblend_s *RESTRICT frameblend, const struct skeleton_s *skeleton, float *RESTRICT vertex3f, float *RESTRICT normal3f, float *RESTRICT svector3f, float *RESTRICT tvector3f)
void(* DrawDepth)(struct entity_render_s *ent)
model_sprite_t sprite
modtype_t type
surfmesh_t surfmesh
qbool lit
int * modelsurfaces_sorted
surface indices of model in an optimal draw order (submodelindex -> texture -> lightmap -> index)
bih_t collision_bih
qbool wanttangents
int submodelsurfaces_end
msurface_t * data_surfaces
void(* Draw)(struct entity_render_s *ent)
float radius
int submodelsurfaces_start
model_brushq3_t brushq3
model_brushq1_t brushq1
void(* DrawSky)(struct entity_render_s *ent)
void(* DrawAddWaterPlanes)(struct entity_render_s *ent)
float lightmapscale
void(* DrawDebug)(struct entity_render_s *ent)
bih_t render_bih
char name[MAX_QPATH]
int num_surfaces
animscene_t * skinscenes
int num_bones
qbool wantnormals
vec3_t normal
Definition model_brush.h:59
vec_t dist
Definition model_brush.h:60
int signbits
Definition model_brush.h:66
describes the textures to use on a range of triangles in the model, and mins/maxs (AABB) for culling.
int num_firsttriangle
int num_triangles
range of triangles and vertices in model->surfmesh
texture_t * texture
the texture to use on the surface
int num_firstvertex
struct rtexture_s * deluxemaptexture
the lighting direction texture fragment to use on the rendering mesh
struct rtexture_s * lightmaptexture
the lightmap texture fragment to use on the rendering mesh
qbool free
Definition progsvm.h:92
union prvm_edict_t::@25 priv
struct edict_engineprivate_s * server
Definition progsvm.h:105
int num_edicts
Definition progsvm.h:670
struct colbrushf_s * colbrushf
q3wavefunc_t wavefunc
Definition r_qshader.h:178
float parms[Q3DEFORM_MAXPARMS]
Definition r_qshader.h:177
float waveparms[Q3WAVEPARMS]
Definition r_qshader.h:179
float parms[Q3TCGEN_MAXPARMS]
Definition r_qshader.h:145
float parms[Q3TCMOD_MAXPARMS]
Definition r_qshader.h:152
float waveparms[Q3WAVEPARMS]
Definition r_qshader.h:154
struct r_bufferdata_buffer_s * purge
Definition gl_rmain.c:3602
r_meshbuffer_t * buffer
Definition gl_rmain.c:3605
qbool ghosttexture_valid
Definition render.h:903
memexpandablearray_t rendertargets
Definition render.h:907
r_rendertarget_t * rt_bloom
Definition render.h:891
float offsettexcoord2f[8]
Definition render.h:899
rtexture_t * ghosttexture
Definition render.h:893
r_waterstate_t water
Definition render.h:901
r_rendertarget_t * rt_screen
Definition render.h:890
textype_t textype
Definition render.h:886
float ghosttexcoord2f[8]
Definition render.h:894
unsigned char * data
Definition gl_rmain.c:3487
struct r_framedata_mem_s * purge
Definition gl_rmain.c:3482
int loc_Texture_FogHeightTexture
Definition gl_rmain.c:743
int tex_Texture_SecondaryNormal
Definition gl_rmain.c:706
int loc_Texture_First
locations of detected uniforms in program object, or -1 if not found
Definition gl_rmain.c:730
int tex_Texture_FogHeightTexture
Definition gl_rmain.c:712
int loc_ScreenCenterRefractReflect
Definition gl_rmain.c:795
int loc_Texture_SecondaryNormal
Definition gl_rmain.c:737
int loc_Texture_ScreenNormalMap
Definition gl_rmain.c:754
int program
0 if compilation failed
Definition gl_rmain.c:697
struct r_glsl_permutation_s * hashnext
hash lookup data
Definition gl_rmain.c:690
int ubibind_Skeletal_Transform12_UniformBlock
uniform block bindings
Definition gl_rmain.c:822
qbool compiled
indicates if we have tried compiling this permutation already
Definition gl_rmain.c:695
int ubiloc_Skeletal_Transform12_UniformBlock
uniform block indices
Definition gl_rmain.c:824
int loc_ScreenScaleRefractReflect
Definition gl_rmain.c:796
unsigned int mode
Definition gl_rmain.c:691
int loc_OffsetMapping_ScaleSteps
Definition gl_rmain.c:786
int loc_DistortScaleRefractReflect
Definition gl_rmain.c:774
int loc_OffsetMapping_LodDistance
Definition gl_rmain.c:787
int tex_Texture_ScreenNormalMap
Definition gl_rmain.c:723
int loc_ModelViewProjectionMatrix
Definition gl_rmain.c:812
skinframe_t * skinframe
Definition gl_rmain.c:304
float ambientintensity
Definition render.h:387
float lightmapintensity
Definition render.h:390
qbool extraupdate
whether to call S_ExtraUpdate during render to reduce sound chop
Definition render.h:352
float rtlightstylevalue[MAX_LIGHTSTYLES]
float fraction of base light value
Definition render.h:380
entity_render_t ** entities
renderable entities (excluding world)
Definition render.h:364
model_t * worldmodel
same as worldentity->model
Definition render.h:361
qbool rtworldshadows
Definition render.h:393
qbool rtdlightshadows
Definition render.h:395
unsigned short lightstylevalue[MAX_LIGHTSTYLES]
8.8 fraction of base light value
Definition render.h:383
entity_render_t * worldentity
the world
Definition render.h:358
double time
(client gameworld) time for rendering time based effects
Definition render.h:355
float viewblend[4]
Definition render.h:419
float fogplaneviewdist
Definition render.h:424
float fogmasktable[FOGMASKTABLEWIDTH]
Definition render.h:432
float fog_height_texcoordscale
Definition render.h:452
qbool oldgl_fogenable
Definition render.h:444
r_refdef_viewcache_t viewcache
Definition render.h:410
char fog_height_texturename[64]
Definition render.h:447
qbool fogenabled
Definition render.h:443
float fog_start
Definition render.h:439
float fog_height_tablescale
Definition render.h:451
float fogheightfade
Definition render.h:426
float polygonoffset
Definition render.h:462
double lastdrawscreentime
Definition render.h:465
float fogmasktable_start
Definition render.h:433
r_refdef_view_t view
Definition render.h:409
float fogmasktabledistmultiplier
Definition render.h:430
float fogcolor[3]
Definition render.h:427
unsigned char * fog_height_table1d
Definition render.h:448
float fog_density
Definition render.h:434
qbool fogplaneviewabove
Definition render.h:425
unsigned char * fog_height_table2d
Definition render.h:449
double farclip
Definition render.h:416
float fog_height
Definition render.h:441
float fogrange
Definition render.h:428
int stats[r_stat_count]
Definition render.h:469
float fog_green
Definition render.h:436
char fogheighttexturename[64]
Definition render.h:453
float fog_alpha
Definition render.h:438
float fog_fadedepth
Definition render.h:442
r_refdef_scene_t scene
Definition render.h:421
double nearclip
Definition render.h:413
qbool envmap
Definition render.h:458
float polygonfactor
Definition render.h:461
float fograngerecip
Definition render.h:429
float fogmasktable_density
Definition render.h:433
float fog_end
Definition render.h:440
float fogplane[4]
Definition render.h:423
int fog_height_tablesize
Definition render.h:450
float fog_blue
Definition render.h:437
float fogmasktable_alpha
Definition render.h:433
float fogmasktable_range
Definition render.h:433
float fog_red
Definition render.h:435
float frustum_y
Definition render.h:277
vec3_t left
Definition render.h:269
qbool useclipplane
Definition render.h:274
qbool clear
whether to call R_ClearScreen before rendering stuff
Definition render.h:305
qbool usecustompvs
uses r_refdef.viewcache.pvsbits as-is rather than computing it
Definition render.h:275
float colorscale
global RGB color multiplier for rendering
Definition render.h:302
qbool showdebug
Definition render.h:314
vec3_t right
Definition render.h:270
int numfrustumplanes
Definition render.h:272
float quality
render quality (0 to 1) - affects r_drawparticles_drawdistance and others
Definition render.h:321
int cullface_back
Definition render.h:318
float frustum_x
Definition render.h:277
vec3_t origin
Definition render.h:267
int useperspective
if turned off it renders an ortho view
Definition render.h:280
mplane_t frustum[6]
Definition render.h:273
qbool isoverlay
if true, don't clear or do any post process effects (bloom, etc)
Definition render.h:307
float ortho_x
Definition render.h:287
r_viewport_t viewport
note: if r_viewscale is used, the viewport.width and viewport.height may be less than width and heigh...
Definition render.h:296
qbool ismain
if true, this is the MAIN view (which is, after CSQC, copied into the scene for use e....
Definition render.h:309
int colormask[4]
which color components to allow (for anaglyph glasses)
Definition render.h:299
matrix4x4_t matrix
Definition render.h:266
int cullface_front
Definition render.h:317
vec3_t frustumcorner[4]
Definition render.h:278
float ortho_y
Definition render.h:287
matrix4x4_t inverse_matrix
Definition render.h:266
vec3_t forward
Definition render.h:268
mplane_t clipplane
Definition render.h:276
int usevieworiginculling
allows visibility culling based on the view origin (e.g.
Definition render.h:286
unsigned char * world_leafvisible
Definition render.h:341
unsigned char * world_pvsbits
Definition render.h:340
qbool world_novis
if true, the view is currently in a leaf without pvs data
Definition render.h:344
unsigned char * world_surfacevisible
Definition render.h:342
unsigned char * entityvisible
which entities are currently visible for this viewpoint (the used range is 0...r_refdef....
Definition render.h:336
rtexture_t * depthtexture
Definition render.h:838
float texcoord2f[8]
Definition render.h:822
textype_t colortextype[4]
Definition render.h:827
rtexture_t * colortexture[4]
Definition render.h:837
struct rtexture_s * texture
Definition r_shadow.h:100
unsigned int loadsequence
Definition gl_rmain.c:2161
skinframe_t * hash[SKINFRAME_HASH]
Definition gl_rmain.c:2163
memexpandablearray_t array
Definition gl_rmain.c:2162
float screentodepth[2]
used by deferred renderer to calculate linear depth from device depth coordinates
Definition render.h:250
matrix4x4_t viewmatrix
actual matrix for rendering (transforms to viewspace)
Definition render.h:241
qbool renderingscene
Definition render.h:879
int maxwaterplanes
Definition render.h:870
float screencenter[2]
Definition render.h:875
int texturewidth
Definition render.h:867
float screenscale[2]
Definition render.h:874
int numwaterplanes
Definition render.h:871
int textureheight
Definition render.h:867
int cameraheight
Definition render.h:868
r_waterstate_waterplane_t waterplanes[MAX_WATERPLANES]
Definition render.h:872
qbool hideplayer
Definition render.h:880
int camerawidth
Definition render.h:868
int waterheight
Definition render.h:866
qbool enabled
Definition render.h:877
unsigned char * pvsbits
Definition render.h:857
r_rendertarget_t * rt_refraction
Definition render.h:852
r_rendertarget_t * rt_camera
Definition render.h:854
r_rendertarget_t * rt_reflection
Definition render.h:853
int numtriangles
Definition render.h:169
float epsilon2
Definition render.h:172
int * element3i
Definition render.h:170
float * vertex3f
Definition render.h:160
int maxvertices
Definition render.h:158
int maxtriangles
Definition render.h:168
int numvertices
Definition render.h:159
int batchskeletalindex4ub_bufferoffset
Definition render.h:699
int batchvertex3f_bufferoffset
Definition render.h:678
int modelskeletalweight4ub_bufferoffset
Definition render.h:651
qbool uselightmaptexture
Definition render.h:741
vec3_t localvieworigin
Definition render.h:731
int * modelelement3i
Definition render.h:652
float * modellightmapcolor4f
Definition render.h:637
int * batchelement3i
Definition render.h:703
unsigned short * batchelement3s
Definition render.h:706
const msurface_t * modelsurfaces
Definition render.h:661
float * entityskeletaltransform3x4
Definition render.h:621
unsigned char * modelskeletalindex4ub
Definition render.h:646
const rtlight_t * rtlight
Definition render.h:751
const msurface_t ** batchmultidrawsurfacelist
Definition render.h:671
int modeltvector3f_bufferoffset
Definition render.h:633
int batchskeletalweight4ub_bufferoffset
Definition render.h:702
int batchelement3s_bufferoffset
Definition render.h:708
float * batchtexcoordlightmap2f
Definition render.h:694
float * batchtexcoordtexture2f
Definition render.h:691
int batchnumtriangles
Definition render.h:675
int batchelement3i_bufferoffset
Definition render.h:705
float inversematrixscale
Definition render.h:726
int modelelement3i_bufferoffset
Definition render.h:654
const r_meshbuffer_t * batchtexcoordlightmap2f_vertexbuffer
Definition render.h:695
float * batchsvector3f
Definition render.h:679
int modelsvector3f_bufferoffset
Definition render.h:630
unsigned short * modelelement3s
Definition render.h:655
matrix4x4_t entitytolight
Definition render.h:757
float fogplaneviewdist
Definition render.h:747
rtexture_t * lightmaptexture
Definition render.h:737
int batchtexcoordlightmap2f_bufferoffset
Definition render.h:696
int modeltexcoordlightmap2f_bufferoffset
Definition render.h:645
int * modellightmapoffsets
Definition render.h:658
const r_meshbuffer_t * modellightmapcolor4f_vertexbuffer
Definition render.h:638
int modelelement3s_bufferoffset
Definition render.h:657
int batchnormal3f_bufferoffset
Definition render.h:687
unsigned char * batchskeletalindex4ub
Definition render.h:697
const r_meshbuffer_t * batchlightmapcolor4f_vertexbuffer
Definition render.h:689
float * modeltvector3f
Definition render.h:631
float basepolygonfactor
Definition render.h:733
float fogheightfade
Definition render.h:746
int batchnumvertices
Definition render.h:673
const r_meshbuffer_t * modeltexcoordlightmap2f_vertexbuffer
Definition render.h:644
const r_meshbuffer_t * batchsvector3f_vertexbuffer
Definition render.h:680
qbool modelgeneratedvertex
Definition render.h:614
float fogmasktabledistmultiplier
Definition render.h:744
float * modeltexcoordtexture2f
Definition render.h:640
int modellightmapcolor4f_bufferoffset
Definition render.h:639
const r_meshbuffer_t * batchtvector3f_vertexbuffer
Definition render.h:683
rtexture_t * deluxemaptexture
Definition render.h:738
int batchlightmapcolor4f_bufferoffset
Definition render.h:690
const r_meshbuffer_t * entityskeletaltransform3x4buffer
Definition render.h:622
float fograngerecip
Definition render.h:743
unsigned char * modelskeletalweight4ub
Definition render.h:649
const r_meshbuffer_t * modelvertex3f_vertexbuffer
Definition render.h:626
const r_meshbuffer_t * batchvertex3f_vertexbuffer
Definition render.h:677
matrix4x4_t matrix
Definition render.h:722
int modelnumtriangles
Definition render.h:660
texture_t * texture
Definition render.h:736
const r_meshbuffer_t * modelnormal3f_vertexbuffer
Definition render.h:635
float * modelsvector3f
Definition render.h:628
int modelnormal3f_bufferoffset
Definition render.h:636
int entityskeletaltransform3x4size
Definition render.h:624
entity_render_t * entity
Definition render.h:770
const r_meshbuffer_t * modelelement3s_indexbuffer
Definition render.h:656
float * modelvertex3f
Definition render.h:625
int batchtvector3f_bufferoffset
Definition render.h:684
int batchfirsttriangle
Definition render.h:674
int entityskeletaltransform3x4offset
Definition render.h:623
const r_meshbuffer_t * modeltvector3f_vertexbuffer
Definition render.h:632
const r_meshbuffer_t * batchtexcoordtexture2f_vertexbuffer
Definition render.h:692
float * batchtvector3f
Definition render.h:682
vec3_t entitylightorigin
Definition render.h:754
int modelskeletalindex4ub_bufferoffset
Definition render.h:648
const r_meshbuffer_t * batchskeletalweight4ub_vertexbuffer
Definition render.h:701
int ent_alttextures
Definition render.h:719
int modelnumvertices
Definition render.h:659
int entityskeletalnumtransforms
Definition render.h:620
const r_meshbuffer_t * batchskeletaltransform3x4buffer
Definition render.h:711
int batchskeletalnumtransforms
Definition render.h:709
int batchfirstvertex
Definition render.h:672
const r_meshbuffer_t * batchelement3i_indexbuffer
Definition render.h:704
float * modeltexcoordlightmap2f
Definition render.h:643
float matrixscale
Definition render.h:725
int modelvertex3f_bufferoffset
Definition render.h:627
int batchskeletaltransform3x4size
Definition render.h:713
frameblend_t frameblend[MAX_FRAMEBLENDS]
Definition render.h:728
float basepolygonoffset
Definition render.h:734
float * modelnormal3f
Definition render.h:634
const r_meshbuffer_t * batchnormal3f_vertexbuffer
Definition render.h:686
int modeltexcoordtexture2f_bufferoffset
Definition render.h:642
const r_meshbuffer_t * modelskeletalindex4ub_vertexbuffer
Definition render.h:647
float userwavefunc_param[Q3WAVEFUNC_USER_COUNT]
Definition render.h:765
int batchskeletaltransform3x4offset
Definition render.h:712
int batchmultidrawnumsurfaces
Definition render.h:670
double shadertime
Definition render.h:720
float * batchvertex3f
Definition render.h:676
unsigned char * batchskeletalweight4ub
Definition render.h:700
float * batchnormal3f
Definition render.h:685
const r_meshbuffer_t * modelelement3i_indexbuffer
Definition render.h:653
const r_meshbuffer_t * modelsvector3f_vertexbuffer
Definition render.h:629
qbool forcecurrenttextureupdate
Definition render.h:613
const r_meshbuffer_t * modelskeletalweight4ub_vertexbuffer
Definition render.h:650
float * batchskeletaltransform3x4
Definition render.h:710
int batchsvector3f_bufferoffset
Definition render.h:681
skeleton_t * skeleton
Definition render.h:729
int batchtexcoordtexture2f_bufferoffset
Definition render.h:693
float fogplane[4]
Definition render.h:745
matrix4x4_t inversematrix
Definition render.h:723
const r_meshbuffer_t * batchelement3s_indexbuffer
Definition render.h:707
const r_meshbuffer_t * batchskeletalindex4ub_vertexbuffer
Definition render.h:698
qbool batchgeneratedvertex
Definition render.h:668
float * batchlightmapcolor4f
Definition render.h:688
qbool batchmultidraw
Definition render.h:669
const r_meshbuffer_t * modeltexcoordtexture2f_vertexbuffer
Definition render.h:641
vec_t ambientscale
ambient intensity to render
Definition client.h:129
rtexture_t * currentcubemap
this is R_GetCubemap(rtlight->cubemapname)
Definition client.h:154
vec3_t currentcolor
Definition client.h:148
vec_t specularscale
specular intensity to render
Definition client.h:133
vec3_t shadoworigin
used only for casting shadows
Definition client.h:139
matrix4x4_t matrix_lighttoworld
matrix for transforming light filter coordinates to world coordinates
Definition client.h:111
vec_t diffusescale
diffuse intensity to render
Definition client.h:131
char qw_skin[MAX_QPATH]
Definition client.h:502
qbool active
false if only a net client
Definition server.h:66
char * builtinstring
Definition gl_rmain.c:619
const char * name
Definition gl_rmain.c:617
const char ** builtinshaderstrings
Definition gl_rmain.c:615
const char * extension
Definition gl_rmain.c:614
const char * sourcebasename
Definition gl_rmain.c:613
const char * pretext
Definition gl_rmain.c:616
const char * pretext
Definition gl_rmain.c:606
struct matrix4x4_s * relativetransforms
Definition protocol.h:426
struct rtexture_s * pants
Definition r_textures.h:130
struct rtexture_s * stain
Definition r_textures.h:127
qbool qgeneratebase
Definition r_textures.h:161
struct rtexture_s * merged
Definition r_textures.h:128
struct rtexture_s * shirt
Definition r_textures.h:131
struct skinframe_s * next
Definition r_textures.h:142
struct rtexture_s * reflect
Definition r_textures.h:136
struct rtexture_s * base
Definition r_textures.h:129
struct rtexture_s * gloss
Definition r_textures.h:133
qbool qhascolormapping
Definition r_textures.h:160
struct rtexture_s * fog
Definition r_textures.h:135
float avgcolor[4]
Definition r_textures.h:155
struct rtexture_s * nmap
Definition r_textures.h:132
qbool qgenerateglow
Definition r_textures.h:164
unsigned int loadsequence
Definition r_textures.h:151
unsigned char * qpixels
Definition r_textures.h:157
struct rtexture_s * glow
Definition r_textures.h:134
qbool qgeneratenmap
Definition r_textures.h:163
char basename[MAX_QPATH]
Definition r_textures.h:143
qbool qgeneratemerged
Definition r_textures.h:162
qbool hasalpha
Definition r_textures.h:153
const char * suffix
Definition gl_rmain.c:2874
qbool flipdiagonal
Definition gl_rmain.c:2875
r_meshbuffer_t * data_svector3f_vertexbuffer
int data_normal3f_bufferoffset
int data_element3s_bufferoffset
int data_skeletalweight4ub_bufferoffset
r_meshbuffer_t * data_lightmapcolor4f_vertexbuffer
r_meshbuffer_t * data_normal3f_vertexbuffer
int data_element3i_bufferoffset
int data_texcoordlightmap2f_bufferoffset
qbool isanimated
int data_skeletalindex4ub_bufferoffset
int data_svector3f_bufferoffset
float * data_lightmapcolor4f
unsigned char * data_skeletalweight4ub
float * data_svector3f
unsigned char * data_skeletalindex4ub
int * data_element3i
unsigned short * data_element3s
r_meshbuffer_t * data_texcoordtexture2f_vertexbuffer
r_meshbuffer_t * data_skeletalindex4ub_vertexbuffer
float * data_vertex3f
r_meshbuffer_t * data_tvector3f_vertexbuffer
r_meshbuffer_t * data_element3i_indexbuffer
float * data_tvector3f
int * data_lightmapoffsets
int data_texcoordtexture2f_bufferoffset
int num_triangles
int data_tvector3f_bufferoffset
r_meshbuffer_t * data_texcoordlightmap2f_vertexbuffer
r_meshbuffer_t * data_skeletalweight4ub_vertexbuffer
int data_vertex3f_bufferoffset
int data_lightmapcolor4f_bufferoffset
float * data_texcoordtexture2f
r_meshbuffer_t * data_element3s_indexbuffer
float * data_normal3f
float * data_texcoordlightmap2f
r_meshbuffer_t * data_vertex3f_vertexbuffer
svbsp_node_t * nodes
Definition svbsp.h:30
q3shaderinfo_layer_tcmod_t tcmods[Q3MAXTCMODS]
Definition r_qshader.h:270
struct skinframe_s * skinframes[TEXTURE_MAXFRAMES]
Definition r_qshader.h:265
q3shaderinfo_layer_tcgen_t tcgen
Definition r_qshader.h:269
float specularpower
struct skinframe_s * backgroundcurrentskinframe
struct rtexture_s * basetexture
int currentblendfunc[2]
float render_rtlight_specular[3]
matrix4x4_t currenttexmatrix
qbool colormapping
struct rtexture_s * glosstexture
float refractfactor
float render_modellight_lightdir_world[3]
float render_glowmod[3]
dptransparentsortcategory_t transparentsort
float render_colormap_pants[3]
struct rtexture_s * nmaptexture
int anim_total[2]
dpoffsetmapping_technique_t offsetmapping
struct rtexture_s * backgroundglosstexture
struct rtexture_s * backgroundbasetexture
int currentmaterialflags
texture_shaderpass_t * backgroundshaderpass
int camera_entity
void * update_lastrenderentity
float render_colormap_shirt[3]
float r_water_waterscroll[2]
float biaspolygonoffset
float basealpha
float render_modellight_diffuse[3]
float render_rtlight_diffuse[3]
float render_modellight_ambient[3]
struct rtexture_s * shirttexture
struct rtexture_s * pantstexture
float specularpowermod
int basematerialflags
struct texture_s * currentframe
float reflectmin
struct rtexture_s * glowtexture
int update_lastrenderframe
vec4_t refractcolor4f
float render_modellight_lightdir_local[3]
struct rtexture_s * backgroundglowtexture
q3shaderinfo_deform_t deforms[Q3MAXDEFORMS]
float render_lightmap_specular[3]
struct rtexture_s * reflectmasktexture
matrix4x4_t currentbackgroundtexmatrix
char name[64]
struct rtexture_s * fogtexture
struct rtexture_s * reflectcubetexture
float render_lightmap_diffuse[3]
float reflectmax
float offsetscale
texture_shaderpass_t * materialshaderpass
float render_lightmap_ambient[3]
float r_water_wateralpha
float specularscalemod
float reflectfactor
struct rtexture_s * backgroundnmaptexture
float offsetbias
float currentalpha
float biaspolygonfactor
float render_modellight_specular[3]
struct skinframe_s * currentskinframe
struct texture_s * anim_frames[2][10]
vec4_t reflectcolor4f
int customblendfunc[2]
double endpos[3]
Definition collision.h:42
float color4f[3][4]
Definition client.h:42
int samples
Definition vid.h:65
int width
Definition vid.h:60
int height
Definition vid.h:61
qbool ext_texture_compression_s3tc
Definition vid.h:48
int glshaderversion
Definition vid.h:45
unsigned int maxtexturesize_2d
Definition vid.h:83
qbool sRGB3D
Definition vid.h:76
qbool sRGB2D
Definition vid.h:75
renderpath_t renderpath
Definition vid.h:80
qbool stencil
Definition vid.h:74
viddef_support_t support
Definition vid.h:89
viddef_mode_t mode
currently active video mode
Definition vid.h:73
qbool allowalphatocoverage
Definition vid.h:81
static vec3_t forward
Definition sv_user.c:305
static vec3_t right
Definition sv_user.c:305
static vec3_t up
Definition sv_user.c:305
void Sys_Error(const char *error,...) DP_FUNC_PRINTF(1) DP_FUNC_NORETURN
Causes the entire program to exit ASAP.
Definition sys_shared.c:706
cvar_t vid_sRGB_fallback
Definition vid_shared.c:158
qbool vid_gammatables_trivial
unsigned int vid_gammatables_serial
@ RENDERPATH_GLES2
Definition vid.h:38
@ RENDERPATH_GL32
Definition vid.h:37
cvar_t vid_sRGB
Definition vid_shared.c:157
viddef_t vid
Definition vid_shared.c:64
void VID_BuildGammaTables(unsigned short *ramps, int rampsize)
#define MOVE_NORMAL
Definition world.h:28
size_t Mem_ExpandableArray_IndexRange(const memexpandablearray_t *l)
Definition zone.c:763
void Mem_ExpandableArray_NewArray(memexpandablearray_t *l, mempool_t *mempool, size_t recordsize, int numrecordsperarray)
Definition zone.c:675
void Mem_ExpandableArray_FreeRecord(memexpandablearray_t *l, void *record)
Definition zone.c:743
void * Mem_ExpandableArray_AllocRecord(memexpandablearray_t *l)
Definition zone.c:695
void * Mem_ExpandableArray_RecordAtIndex(const memexpandablearray_t *l, size_t index)
Definition zone.c:780
mempool_t * tempmempool
Definition zone.c:794
void Mem_ExpandableArray_FreeArray(memexpandablearray_t *l)
Definition zone.c:683
#define Mem_Free(mem)
Definition zone.h:96
#define Mem_Alloc(pool, size)
Definition zone.h:92
#define Mem_strdup(pool, s)
Definition zone.h:97
#define Mem_AllocPool(name, flags, parent)
Definition zone.h:104